#include<iostream> #include<cstdio> using namespace std; #define MAX(a,b) (a>b)?a:b const int SIZE=1000+16; int nKind; //物品种类数目 int nLimit; //背包容量 int val[SIZE]; //每种背包的价值 int weight[SIZE]; //每种背包的重量 int bag[SIZE]; //每种背包的数目 int dp[SIZE]; //0-1背包, 代价为cost, 获得的价值为value void ZeroOnePack(int cost, int value) { for(int i=nLimit; i>=cost; i--) //逆序 { dp[i]=MAX(dp[i], dp[i-cost]+value); } } //完全背包, 代价为cost, 获得的价值为value void CompletePack(int cost, int value) { for(int i=cost; i<=nLimit; i++) //顺序 { dp[i]=MAX(dp[i],dp[i-cost]+value); } } //多重背包 代价为cost, 获得的价值为value, 该种背包的数目为amount void MultiplePack(int cost, int value, int amount) { if(cost*amount>=nLimit) CompletePack(cost, value); else { int k=1; while(k<amount) { ZeroOnePack(k*cost, k*value); amount-=k; k<<=1; } ZeroOnePack(amount*cost, amount*value); } } int main() { //不要求装满则dp中的元素均为零; //否则dp[0]=0.其他为 -INF memset(dp,0,sizeof(dp)); scanf("%d %d",&nKind,&nLimit); for(int i=0;i<nKind;i++) { scanf("%d %d %d",&weight[i],&val[i],&bag[i]); } for(int i=0; i<nKind; i++) MultiplePack(weight[i],val[i],bag[i]); printf("%d ",dp[nLimit]); return 0; }