为什么不会产生缝隙问题?
二进制优化是正确的,一开始我在想这一个一个大包这么大,装到背包里如果背包的空间没有被充分利用怎么办,不是没有最优解了吗?为什么二进制优化是对的呢?原来使用二进制优化将物品拆包为1,2,4…2^k个包的时候,我们可以利用之前的这些包的数来凑出0-2^(k+1)-1的所有整数
我们使用样例来模拟一下
样例模拟
1 2 4 8 16 32 64 128 256 512 1024
这十一个数可以拼凑出0-2047间的所有整数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16................
1 2 1+2 4 4+1 4+2 4+2+1 8 8+1 8+2 8+2+1 8+4 8+4+1 8+4+2 8+4+2+1 16................
所以在使用二进制将si个i物品拆包组装成一个个大包之后我们总归可以通过01背包的枚举方式来得到一个正确的i物品选用数量,比如说应该选67件i物品,那么体现成我们选取了 价值为64w的物品一件 + 价值为2w的物品一件 + 价值为1*w的物品一件
完整代码
#include<iostream>
using namespace std;
const int N=25010;
int n,m;
int v[N],w[N];
int f[N];
int main()
{
int cnt=0;
cin>>n>>m;
for(int i=1;i<=n;i++) //
{ //
int v1,w1,s1; //
cin>>v1>>w1>>s1; //
for(int j=1;j<=s1;)//拆包分包
{ //
cnt++; //
v[cnt]=v1*j; //
w[cnt]=w1*j; //
s1-=j; //
j*=2; //
} //
if(s1>0) //
{ //
cnt++; //
v[cnt]=v1*s1; //
w[cnt]=w1*s1; //
} //
} //
for(int i=1;i<=cnt;i++)
{
for(int j=m;j>=v[i];j--)
{
f[j]=max(f[j],f[j-v[i]]+w[i]);//来做一遍01背包问题就结束了
}
}
cout<<f[m];
return 0;
}
若子在牢内好好打代码,出来重新做人
爱若信若等若
s1-=j; //这句话是干嘛用的
喂喂喂
看前面的没太明白,看到你这就懂了哈哈哈哈
懂了 🐂
byd 你这id和头像就难绷
别吵别吵别吵
非常感谢!!
啊!我恍然大悟!!!!!!1
哈哈,很高兴帮到你
一看就懂了!! orz
^^
有没有多重3的题解?推荐哪一篇?谢谢。
并不是想看题解,就是想进来说一句,uzi,永远滴神!!!
thank
^^