题目地址:点击打开链接
思路:看本博客背包类Tianyi Cui大神写的背包九讲,以及代码后的解释
AC代码:
#include<stdio.h> #include<string.h> int p[120],h[120],c[120],v[120]; int n,m; int max(int a,int b) { return a > b ? a : b; } void zeroone_pack(int money,int weight) { int i; for(i=n; i>=money; i--) { v[i] = max(v[i],v[i-money] + weight); } } void complete_pack(int money,int weight) { int i; for(i=money; i<=n; i++) { v[i] = max(v[i],v[i-money] + weight); } } void multi_pack() { int i,count,k; for(i=0; i<m; i++) { if(p[i] * c[i] >= n)//这个种类的大米可以取到背包满,所以转化为完全背包 { complete_pack(p[i],h[i]); } else//转化为01背包 { k = 1; count = c[i]; //while(k < n) //while(k < c[i])以后还要用c[i]的值进行运算,所以这个判断错误 while(k < count)//看最后面注释 { zeroone_pack(k*p[i],k*h[i]); count -= k; k *= 2; } zeroone_pack(count*p[i],count*h[i]); } } printf("%d\n",v[n]); } int main() { int t,i; scanf("%d",&t); while(t--) { memset(v,0,sizeof(v)); scanf("%d%d",&n,&m); for(i=0; i<m; i++) { scanf("%d%d%d",&p[i],&h[i],&c[i]);//注意有重名的情况 } multi_pack(); } return 0; }
k=1 | count=13 |
count=12 | |
k=2 | count=12 |
count=10 | |
k=4 | count=10 |
count=6 | |
k=8 | count=6 |
退出循环 |