HDU 2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包基础题)
2017-11-25 20:27
393 查看
HDU2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
http://acm.hdu.edu.cn/showproblem.php?pid=2191
题意:
假设你有资金n元, 然后有m种大米, 每种大米价格为cost[i], 重量为val[i], 数量为num[i]. 现在有n元钱,去买大米,求大米的最大重量。
分析:
本题是典型的多重背包问题.(背包容量为总金额n元,物体体积为单价,价值为物体的重量)
dp[i][j]:表示购买前i种大米,且总费用<=j时能购买的大米最大重量.
边界控制: dp为全0.
由于每种大米有数量num[i], 所以我们分下面两种情况做:
当cost[i]*num[i]>=n时(容量*个数>=背包容量), 我们直接对该种大米做一次完全背包过程即可.
当 cost[i]*num[i]<n时, 我们把num[i]个第i类大米看成下面k+1种物品:
1个(i类物品) 2个 4个 2^(k-1)个 以及 num[i]-2^k+1个
我们对上述k+1种新物品每个都做一个01背包即可覆盖我们可能对第i种物品做出的所有选择(2进制哟).
最终所求: dp[m]
的值.
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n, m;//总金额和大米种类
int cost[105], value[105], num[105];//价格 重量 数量
int
4000
dp[105];
//一次01背包
void Zero_One_Pack(int cost, int value)
{
for (int i = n; i >= cost; i--)
dp[i] = max(dp[i], dp[i - cost] + value);
}
//一次完全背包
void Complete_Pack(int cost, int value)
{
for (int i = cost; i <= n; i++)
dp[i] = max(dp[i], dp[i - cost] + value);
}
//一次多重背包
void Multi_Pack(int cost, int val, int num)
{
if (cost*num >= n)
{
Complete_Pack(cost, val); return;
}
int k = 1;
while (k < num)
{
Zero_One_Pack(k*cost, k*val);
num -= k;
k *= 2;
}
Zero_One_Pack(num*cost, num*val);
}
int main()
{
int T; cin >> T;
while (T--)
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
cin >> cost[i] >> value[i] >> num[i];
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= m; i++)
Multi_Pack(cost[i], value[i], num[i]);
cout << dp
<< endl;
}
system("pause");
}
http://acm.hdu.edu.cn/showproblem.php?pid=2191
题意:
假设你有资金n元, 然后有m种大米, 每种大米价格为cost[i], 重量为val[i], 数量为num[i]. 现在有n元钱,去买大米,求大米的最大重量。
分析:
本题是典型的多重背包问题.(背包容量为总金额n元,物体体积为单价,价值为物体的重量)
dp[i][j]:表示购买前i种大米,且总费用<=j时能购买的大米最大重量.
边界控制: dp为全0.
由于每种大米有数量num[i], 所以我们分下面两种情况做:
当cost[i]*num[i]>=n时(容量*个数>=背包容量), 我们直接对该种大米做一次完全背包过程即可.
当 cost[i]*num[i]<n时, 我们把num[i]个第i类大米看成下面k+1种物品:
1个(i类物品) 2个 4个 2^(k-1)个 以及 num[i]-2^k+1个
我们对上述k+1种新物品每个都做一个01背包即可覆盖我们可能对第i种物品做出的所有选择(2进制哟).
最终所求: dp[m]
的值.
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n, m;//总金额和大米种类
int cost[105], value[105], num[105];//价格 重量 数量
int
4000
dp[105];
//一次01背包
void Zero_One_Pack(int cost, int value)
{
for (int i = n; i >= cost; i--)
dp[i] = max(dp[i], dp[i - cost] + value);
}
//一次完全背包
void Complete_Pack(int cost, int value)
{
for (int i = cost; i <= n; i++)
dp[i] = max(dp[i], dp[i - cost] + value);
}
//一次多重背包
void Multi_Pack(int cost, int val, int num)
{
if (cost*num >= n)
{
Complete_Pack(cost, val); return;
}
int k = 1;
while (k < num)
{
Zero_One_Pack(k*cost, k*val);
num -= k;
k *= 2;
}
Zero_One_Pack(num*cost, num*val);
}
int main()
{
int T; cin >> T;
while (T--)
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
cin >> cost[i] >> value[i] >> num[i];
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= m; i++)
Multi_Pack(cost[i], value[i], num[i]);
cout << dp
<< endl;
}
system("pause");
}
相关文章推荐
- HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包,经典入门题)
- hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(dp多重背包)
- HDU 2191 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活(多重背包)
- HDU-2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 ( 多重背包 )
- hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
- HDU--杭电--2191--悼念512汶川大地震遇难同胞——珍惜现在,感恩生活--背包
- hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 多重背包
- HDU-2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
- hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 (多重背包)
- HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 多重背包
- 【DP|多重背包】HDU-OJ-2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
- HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 背包
- 多重背包之 HDU -1171Big Event in HDU &HDU -2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
- HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
- hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 (dp 多重背包)
- HDU-2191-悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
- HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 动态规划多重背包
- hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 (多重背包)
- HDU 2191:悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 (多重背包)
- HDU 2191 - 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)