多重背包Ⅱ
多重背包Ⅱ其实就是数据范围扩大了,不能写像昨天y总三层循环的那样了
然后然后然后新的做法似曾相识,嘿嘿嘿。这不就是我喜欢的简单粗暴的拆成01背包的那种做法吗
不过啦,数据范围是1000,那么简单粗暴行不通,必超时,所以在那个基础上进行二进制优化
哈哈哈,二进制优化真简单,一看就懂~(吹牛逼的)
反之
看了好几遍没看懂....
但是结合几个大佬的讲解,我有了自己的一种新的境界~~(仙气飘飘)
好了啊,废话不多说,直接上题
有
第
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,
接下来有
输出格式
输出一个整数,表示最大价值。
数据范围
提示:
本题考查多重背包的二进制优化方法。
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10
这个题思路啥的我都知道了,就是二进制开优化有点懵懵的,怎么说呢,举个例子吧
原来直接枚举的时候,比如有10个,可能选到第7个是最优解
然后后面三个枚举到的时候就是呈现不选的状态
用二进制优化的时候,2^0,2^1,2^2...把这些数字分堆,依然可以达到一一枚举的效果
比如10里7还是最优解
1 2 4 8
1+2+4==7
就是emm怎么说呢
后面的数字分为一堆,就不用一一枚举了,前面的数相加可以达到7的这个效果,,,这么说吗?
自己悟吧,哈哈...
#includeusing namespace std; const int N=1e5+10; int f[N],v[N],w[N]; int main(){ int n,m; cin>>n>>m; int t=0; for(int i=0;i ) { int a,b,c; cin>>a>>b>>c; int k=1; while(k<=c) { t++; v[t]=a*k;//t就是存数组的下标 w[t]=b*k;//k是二进制分堆 c-=k;//已经分出去的份数 k*=2;//二进制优化, } if(c>0) { t++; v[t]=a*c; w[t]=b*c; } } n=t; for(int i=1;i<=n;i++) { for(int j=m;j>=v[i];j--) { f[j]=max(f[j],f[j-v[i]]+w[i]); } } cout< endl; return 0; }
看代码还是容易理解的,没啥好说的了,加油吧!!