混合背包
#include<bits/stdc++.h> using namespace std; const int maxn=1000+10; int n,k,w[maxn],v[maxn],dp[10*maxn]={0},nw[10*maxn],nv[10*maxn],cnt=0,c[maxn]; //计算出完全背包最多多少个,就变成了多重背包,01页看成多重,直接用二进制变成01,然后dp //也可以完全背包不转化,用标记来和01区分,然后dp时根据不同的类型进行不同的for循环,可以滚动数组,这样快因为完全背包优化过了 //也可以直接对所有的分类,根据0 1 2,进行选择然后for循环,有完全背包的优化,快 int main() { cin>>n>>k; for(int i=1;i<=n;i++){ cin>>w[i]>>v[i]>>c[i]; if(c[i]==-1) c[i]=1; if(c[i]==0) c[i]=k/w[i];//最多1000次 } for(int i=1;i<=n;i++){ for(int j=1;j<=c[i];j<<=1){ c[i]-=j; nv[++cnt]=v[i]*j; nw[cnt]=w[i]*j; } if(c[i]>0){ nv[++cnt]=v[i]*c[i]; nw[cnt]=w[i]*c[i]; } } for(int i=1;i<=cnt;i++){ for(int j=k;j>=nw[i];j--){ dp[j]=max(dp[j],dp[j-nw[i]]+nv[i]); } } cout<<dp[k]<<endl; return 0; }