把他拆分二进制,然后可以用这些一堆2i(1-cnt)来组合成0-s的数,
如果不能形成想象的二进制数,那我们就把最后的没能形成的作为一部分算进去。然后变成一个背包问题。
可能到这一步你们还没有理解,比如说
7的二进制数是111
可以变成14+12+1*1
因为二进制最大是1,也就是只能用一次,背包问题同样也是,背包问题没搞明白的话,可以去看看以前的博文链接
所以代码就非常的简单了。
代码如下
#include<iostream>
#include<algorithm>
using namespace std;
const int N=25000,M=2010;
int cnt;
int vi[N],wi[N],f[M];
int n,m;
int main(void)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int v,w,s;
scanf("%d%d%d",&v,&w,&s);
int k=1;
while(k<s)
{
cnt++;
vi[cnt]=v*k;
wi[cnt]=w*k;
s-=k;
k*=2;
}
if(s)
{
cnt++;
vi[cnt]=v*s;
wi[cnt]=w*s;
}
}
for(int i=1;i<=cnt;i++)
for(int j=m;j>=vi[i];j--)
f[j]=max(f[j],f[j-vi[i]]+wi[i]);
cout<<f[m];
}