题目传送门
解题思路:
可以转化成0-1背包来做,但暴力转化的话,时间不允许.所以就用了一个二进制划分的方法,将m个物品分成2,4,8,16,32......(2的次方)表示,可以证明这些数通过一定组合可以表示任何数.然后跑0-1背包即可.
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 int n,m,c[100001],w[100001],f[40001],num,tot,_c,_w; 7 8 int main() { 9 scanf("%d%d",&n,&m); 10 for(int i = 1;i <= n; i++) { 11 scanf("%d%d%d",&_c,&_w,&num); 12 for(int j = 1;j <= num; j *= 2) { 13 c[++tot] = j * _c; 14 w[tot] = j * _w; 15 num -= j; 16 } 17 if(num != 0) { 18 c[++tot] = _c * num; 19 w[tot] = _w * num; 20 } 21 } 22 for(int i = 1;i <= tot; i++) 23 for(int j = m;j >= w[i]; j--) 24 f[j] = max(f[j],f[j-w[i]] + c[i]); 25 printf("%d",f[m]); 26 return 0; 27 }