题解:融合了几种背包问题
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int M=210;
#define Mv MAXV
int w[M],v[M],num[M];
int f[M*1000];
int T,n,m;
int Mv;
inline void ZOPack(int w,int v)
{
for(int j=Mv;j>=w;j--)
if(f[j-w]+v>f[j])
f[j]=f[j-w]+v;
}
inline void CPack(int w,int v)
{
for(int j=w;j<=Mv;j++)
if(f[j-w]+v>f[j])
f[j]=f[j-w]+v;
}
inline void MPack(int w,int v,int amount)
{
if(amount*w>=Mv)
{
CPack(w,v);
return ;
}
for(int k=1;k<=amount;k<<=1)//可以二进制拆分的
{
ZOPack(k*w,k*v);
amount-=k;
}
ZOPack(amount*w,amount*v);//拆分剩下的
}
void init()
{
memset(f,0,sizeof(f));
cin>>m>>Mv;
for(int i=1;i<=m;i++)
cin>>w[i]>>v[i]>>num[i];
}
int main()
{
init();
for(int i=1;i<=m;i++)
{
if(num[i]==1)
ZOPack(w[i],v[i]);
else if(num[i]==-1)
CPack(w[i],v[i]);
else
MPack(w[i],v[i],num[i]);
}
cout<<f[Mv]<<endl;
return 0;
}