题目:垃圾陷阱
思路:
一个一点都不可爱的小背包。
状态f[i][j]表示前i个垃圾,填了j高度的最大生命值。(这比前i个垃圾,填了生命值为j的最大高度要好做)
转移方程:
if(j>=a[i].h&&f[i-1][j-a[i].h]>=a[i].t) f[i][j]=max(f[i][j],f[i-1][j-a[i].h]);
if(f[i-1][j]>=a[i].t) f[i][j]=max(f[i][j],f[i-1][j]+a[i].f);
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 100
#define maxt 1000
#define read(x) scanf("%d",&x)
struct rb{
int t,f,h;
rb(){}
rb(int tt,int ff,int hh) {
t=tt,f=ff,h=hh;
}
bool operator < (const rb& oth) const {
return t<oth.t;
}
};
int n,m;
rb a[maxn+5];
int f[maxn+5][maxt+5];
int main() {
read(m),read(n);
for(int i=1;i<=n;i++) read(a[i].t),read(a[i].f),read(a[i].h);
sort(a+1,a+n+1);
f[0][0]=10;
for(int i=1;i<=n;i++) {
for(int j=0;j<=m;j++) {
if(j>=a[i].h&&f[i-1][j-a[i].h]>=a[i].t) f[i][j]=max(f[i][j],f[i-1][j-a[i].h]);
if(f[i-1][j]>=a[i].t) f[i][j]=max(f[i][j],f[i-1][j]+a[i].f);
}
}
int ans=0,s=0;
for(int i=1;i<=n;i++) {
if(f[i][m]-a[i].t>=0) {s=i;break;}
ans=max(ans,f[i][0]);
}
if(!s) printf("%d",ans);
else printf("%d",a[s].t);
return 0;
}