//多重背包的二进制优化的空间优化
/*
观念:
把多个相同的物品合并成为一个大物品
如何合并:
使用二进制把每一类物品的总个数进行拆分,这样每一种组合(选择这种物品的个数)都能通过选择这些大物品凑成,而且物品数量变成了n*log级别
例1:6个1
可以凑成0,1,2,3,4,5,6
变成1,2,3后也能凑成0,1,2,3,4,5,6
例2:10个2
可以凑成0,2,4,6,...,20
变成1,2,4,3后也能凑成0,2,4,6,...,20
*/
#include<bits/stdc++.h>
using namespace std;
const int MAXG=2e6+1,MAXM=2e5+1;//二进制优化后最大物品个数和背包容量的最大值
int n,m,v[MAXG],w[MAXG],dp[MAXM],id,win,vin,s;
/*
有n种物品,背包容量为m,每一种物品有v价值,w重量,s个数
dp为滚动数组
id为物品个数
*/
int main(){
scanf("%d%d",&n,&m);//n个物品,背包容量为m
for(int i=1;i<=n;i++){
scanf("%d%d%d",&vin,&win,&s);
//对s[i]进行二进制拆分
int f=1;
while(f<=s){//拆分到拆不动为止
w[++id]=win*f;
v[id]=vin*f;
s-=f;
f*=2;//按照2的幂次进行拆分
}
if(s){//拆分存在剩余
w[++id]=win*s;
v[id]=vin*s;
}
}
for(int i=1;i<=id;i++){//有id件物品
for(int j=m;j>=w[i];j--){//01背包的做法
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);//状态转移方程
}
}
cout<<dp[m];
return 0;
}