有限制的 0/1背包
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N = 30+5;
typedef long long ll;
map<ll,ll> dp[3];
map<ll,ll>::iterator it;
struct node
{
int l,t,v;
}p[N];
int cmp(node a,node b)
{
return a.l-a.t < b.l-b.t;
}
int main(){
int n;
ll w,sum;
while(scanf("%d%lld",&n,&w)!=EOF){
sum = 0;
for(int i=1;i<=n;i++){
scanf("%d%d%d",&p[i].t,&p[i].v,&p[i].l);
sum += p[i].v;
}
if(sum < w){
puts("zhx is naive!");
continue;
}
sort(p+1,p+1+n,cmp);
for(int i=0;i<=1;i++) dp[i].clear();
int now = 0;
int pre = 1;
dp[now][0] = 0;
for(int i=1;i<=n;i++){
now ^= 1;
pre ^= 1;
dp[now].clear();
for(it=dp[pre].begin();it!=dp[pre].end();it++){
ll pre_v = it->second;
ll pre_t = it->first;
dp[now][pre_t] = max(dp[now][pre_t],dp[pre][pre_t]);
ll tmp = max(pre_t+p[i].t,(ll)p[i].l);
dp[now][tmp] = max(dp[now][tmp],dp[pre][pre_t]+(ll)p[i].v);
}
}
ll ans = 1e15;
for(it=dp[now].begin();it!=dp[now].end();it++){
if(it->second >= w && it->first < ans){
ans = it->first;
}
}
if(ans==-1) puts("zhx is naive!");
else
printf("%d\n",ans);
}
return 0;
}