【解题报告】【HDOJ2602】【01背包】Bone Collector
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602
1.此题的约束条件volume是整形的。用三个数组,volume,value和record,分别记录体积,价值,和判断后的价值,record的下标代表空间,其值代表判断i个物品后各个空间的总价值。
2.对于每一个物品,考虑每一种空间的情况,如第一个物品时,空间为10时,有两种情况,一是不取,二是取,然后将其值和剩下空间能得到的最大价值相加,选取两者中价值最大的。如如第一次判断时,物品1的volume是5,value是1,当V=10时,初始化时,record都置零,那么此时,record[10]=0,record[5]=0,而物品1的价值为1,record[5]+value1>record[10],所以选择取的情况,record[10]也变成了0+1=1。
3.在核心代码部分V用了逆序,是因为判断record[10]的时候,需要用到record[5]时的值,若果先运算了record[5],那么值可能会改变,那么导致一样东西选取了两次,顺序方法适用于完全背包问题。当然,本题也可以用两个数组和顺序的方法,但浪费了时间和空间。
1 #include<stdio.h> 2 #include<string.h> 3 #define max 1002 4 int main() 5 { 6 long int record[max],volume[max],value[max]; 7 long int n,v,T,i,j; 8 scanf("%ld",&T); 9 while(T--) 10 { 11 scanf("%ld%ld",&n,&v); 12 memset(record,0,sizeof(record)); 13 for(i=1;i<=n;i++) 14 scanf("%ld",&value[i]); 15 for(i=1;i<=n;i++) 16 scanf("%ld",&volume[i]); 17 for(i=1;i<=n;i++) 18 for(j=v;j>=volume[i];j--) 19 if(record[j-volume[i]]+value[i]>record[j]) 20 record[j]=record[j-volume[i]]+value[i]; 21 22 printf("%ld\n",record[v]); 23 } 24 return 0; 25 }