题意:有n种物品,每件物品的价值为pr[i],体积为v[i],重量为w[i],数量为c[i]。现有一个体积为V,最大可承受重量为W的背包。问:怎么样选择物品,使得背包中的物品价值最大?
分析:这题其实与上一题差不多,思路是一样的,只是多了一维,相应的记录数组也多一维就搞定。仍然是以二进制的思想来进行优化。不过因为数组变成了二维,所以数组不能开得太大。其实,不管多重背包变成多少维,解题的思路是一样的,只是相应进行一些改变而已。所以理解01背包的思想,再加上相应的灵活转化就能搞定问题。
(我想如果维数达到一定的程度,这种方法就不适用了,因为数组的维数大了,它的宽度就小了,这也就不一定能满足所需。)
code:
#include<stdio.h>
#include<string.h>
#define N 600 //N 不能太大了
int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int i, j, k, n;
int V, W, p;
int c[10], w[10], pr[10],v[10];
int f[N][N];
while(scanf("%d", &n) != EOF)
{
scanf("%d%d", &V, &W);
for(i = 1; i <= n; i++)
scanf("%d %d %d %d", &v[i], &w[i], &c[i], &pr[i]);
memset(f, 0, sizeof(f));
for(i = 1; i <= n; i++) //(二维)多重背包转化成01背包
{
for(j = 1; j <=c[i]; j *=2)
{
for(k = W; k >= j*w[i]; k--) //就是再加这一维就行了
{
for(p = V; p >= j*v[i]; p--)
{
f[k][p] = max(f[k][p], f[k-j*w[i]][p-j*v[i]]+j*pr[i]);
}
}
c[i] -= j;
}
j = c[i];
for(k = W; k >= j*w[i]; k--)
{
for(p = V; p >= j*v[i]; p--)
{
f[k][p] = max(f[k][p], f[k-j*w[i]][p-j*v[i]]+j*pr[i]);
}
}
}
printf("%d\n",f[W][V]);
}