c/c++语言开发共享多重背包模板

2019-01-19 多重背包:每种东西有多个,因此可以把它拆分成多个01背包 优化:二进制拆分(拆成1+2+4+8+16+…,分别表示2的n次幂) 比如18=1+2+4+8+3,可以证明18以内的任何数都可以用这几个数的和或差表示(每个数只能用一次)(0时则背包为空), 所以就把2个,4个.. …

2019-01-19

多重背包:每种东西有多个,因此可以把它拆分成多个01背包

优化:二进制拆分(拆成1+2+4+8+16+…,分别表示2的n次幂)

比如18=1+2+4+8+3,可以证明18以内的任何数都可以用这几个数的和或差表示(每个数只能用一次)(0时则背包为空),

所以就把2个,4个….绑定为一个物品,和一个一个的效果是一样的

这样就减少了拆分出来的物品的数量。(从n到log n)

代码

 1 #include<cstdio>  2 using namespace std;  3 const int maxn = 200005;  4 int n,m,a,b,c,cnt,ans,f[maxn],v[maxn],w[maxn];  5 int main() {  6     scanf("%d%d",&n,&m);  7     for(int i = 1;i <= n;i++){  8         scanf("%d%d%d",&a,&b,&c);  9         for(int j = 1;j <= c;j *= 2){ 10             c -= j; 11             v[++cnt] = a*j;//区分++cnt和cnt++  12             w[cnt] = b*j; 13         } 14         if(c){ 15             v[++cnt] = a*c; 16             w[cnt] = b*c; 17         } 18     } 19     for(int i = 1;i <= cnt;i++)  20         for(int j = m;j >= w[i];j--){ 21             f[j] = max(f[j],f[j-w[i]]+v[i]); 22             ans = max(f[j],ans); 23         } 24     printf("%d",ans); 25     return 0; 26 }

 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/605481.html

(0)
上一篇 2021年5月13日
下一篇 2021年5月13日

精彩推荐