背包问题前几篇文章:
有n种物品,每种物品的单件体积为v[i],价值为w[i]。现有一个容量为V的背包,问如何选取物品放入背包,使得背包内物品的总价值最大。其中每种物品有s[i]件。
多重背包和完全背包、01背包区别:

原题测试样例不容易看出规律,因此使用其他的测试样例:
输入样例:
3 7qu
2 3 12
2 5 15
1 2 3
输出样例:
12
01背包:第i件物品可以取0件,可以取1件
多重背包:第i件物品可以取0件,取1件、取2件······取s[i]件
多重背包转化为01背包求解:把第i件物品换成s[i]件01背包中的物品,每件物品的体积为k* v[i],价值为k * w [i] (0<=k<=s[i])
核心代码:
for(i=1;i<=n;i++)
for(j=m;j>=v[i];j--)
for(k=0;k<=s[i]&&k*v[i]<=j;k++)
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);

样例可以表示为:

二进制优化核心代码:
int cnt=0;//计数器
for(int i=1;i<=n;i++)
{
int a,b,s;
cin>>a>>b>>s;
int k=1;
//二进制拆分
while(k<=s)
{
cnt++;
v[cnt]=a*k;
w[cnt]=b*k;
s-=k;
k*=2;
}
if(s>0)//剩余
{
cnt++;
v[cnt]=a*s;
w[cnt]=b*s;
}
}
拆分完之后就变成了:

优化完之后在用一次01背包:
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]);
cout<<f[m]<<endl;