http://codevs.cn/problem/3269/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,dp[200005],v[200005],w[200005],num[200005];
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i ++)
scanf("%d%d%d",&w[i],&v[i],&num[i]);
for(int i = 1;i <= n;i ++)
{
if(num[i] == -1)
for(int j = w[i];j <= m;j ++)
dp[j] = max(dp[j],dp[j - w[i]] + v[i]);
else if(num[i] == 1)
for(int j = m;j >= w[i];j --)
dp[j] = max(dp[j],dp[j - w[i]] + v[i]);
else
{
int ji = 1,l = num[i]; //二进制拆分;
while(num[i] >> 1)//为了避免拆完后的总价值高于总价值,提前一步跳出
{
for(int j = m;j >= w[i] * ji;j --)
dp[j] = max(dp[j],dp[j - w[i] * ji] + v[i] * ji);
l -= ji;//记录还剩下多少可用的物品;
num[i] >>= 1;
ji <<= 1;
}
for(int j = m;j >= w[i] * l;j --)
dp[j] = max(dp[j],dp[j - w[i] * l] + v[i] * l);
}
}
printf("%d",dp[m]);
}