题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2191
题目大意:现在你一共有资金n元,市场上有m中大米,每种大米都是袋装的,而且价格不等,购买大米时只能整袋购买。现在问在有限的资金下最多能够购买多少公斤的大米。
方法:多重背包,对于每种大米的选择,能够用完全背包就用完全背包进行优化,不能够用完全背包优化就进行二进制优化。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 202
#define max(x,y) (x>y?x:y)
struct node
{
int val, weight, d;
}p[maxn];
int dp[maxn];
int main()
{
int ncase, v, n;
scanf("%d", &ncase);
while (ncase--)
{
scanf("%d%d", &v, &n);
for (int i=0; i<n; ++i)
scanf("%d %d %d", &p[i].weight, &p[i].val, &p[i].d);
memset(dp, 0, sizeof(dp));
for (int i=0; i<n; ++i)
{
if (p[i].weight*p[i].d>=v)//完全背包优化
{
for (int j=p[i].weight; j<=v; ++j)
dp[j] = max(dp[j], dp[j-p[i].weight]+p[i].val);
continue;
}
//以下是二进制优化
int k = 1;
while (k<p[i].d)
{
for (int j=v; j>=k*p[i].weight; --j)
dp[j] = max(dp[j], dp[j-k*p[i].weight]+k*p[i].val);
p[i].d -= k;
k *= 2;
}
for (int j=v; j>=p[i].d*p[i].weight; --j)
dp[j] = max(dp[j], dp[j-p[i].d*p[i].weight]+p[i].d*p[i].val);
}
printf("%d\n", dp[v]);
}
return 0;
}