P1156 垃圾陷阱
(01背包-DP)
设状态
f
[
i
]
f[i]
f[i]表示奶牛高度为
i
i
i时可以存活的最久时间
首先,先将所有垃圾按丢下来的时间升序排序,并初始化
f
[
0
]
=
10
f[0]=10
f[0]=10
其次,对于每一个垃圾i,枚举当前的高度
j
j
j
如果
f
[
j
]
f[j]
f[j]小于垃圾
i
i
i掉下的时间,直接
c
o
n
t
i
n
u
e
continue
continue
如果当前的高度加上这个垃圾的高度(前提是可以存活到当前时间)超过了井口高度,就输出垃圾
i
i
i的掉落时间
然后,考虑分别考虑吃和不吃来更新
吃的话,高度不会变高,而存活时间增加,则f[j]+=
垃圾
i
i
i维持生命的时间
拿来垫高的话,就更新垫高后的高度的生命时间f[j+a[i].h]=max(f[j+a[i].h],f[j])
最后,如果还没有找到答案,说明不可能逃出去,就吃掉所有垃圾,输出存活时间
f
[
0
]
f[0]
f[0]
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int Maxn=110;
int f[Maxn],n,m;
struct thing{
int t,v,h;
}a[Maxn];
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
inline bool cmp(thing x,thing y)
{
return x.t<y.t;
}
int main()
{
//freopen("in.txt","r",stdin);
m=read(),n=read();
for(int i=1;i<=n;++i)
a[i].t=read(),a[i].v=read(),a[i].h=read();
sort(a+1,a+1+n,cmp);
f[0]=10;
for(int i=1;i<=n;++i)
for(int j=m;j>=0;--j)
{
if(f[j]<a[i].t)continue;
if(j+a[i].h>=m){printf("%d\n",a[i].t);return 0;}
f[j+a[i].h]=max(f[j+a[i].h],f[j]);
f[j]+=a[i].v;
}
printf("%d\n",f[0]);
return 0;
}