题目描述
卡门――农夫约翰极其珍视的一条\(Holsteins\)奶牛――已经落了到“垃圾井”中 . “垃圾井”是农夫们扔垃圾的地方 ,它的深度为\(D(2≤D≤100)\)英尺 .
卡门想把垃圾堆起来 ,等到堆得与井同样高时 ,她就能逃出井外了 . 另外 ,卡门可以通过吃一些垃圾来维持自己的生命 .
每个垃圾都可以用来吃或堆放 ,并且堆放垃圾不用花费卡门的时间 .
假设卡门预先知道了每个垃圾扔下的时间\(t(0< t \le 1000)\) ,以及每个垃圾堆放的高度\(h(1 \le h \le 25)\)和吃进该垃圾能维持生命的时间\(f(1 \le f \le 30)\) ,要求出卡门最早能逃出井外的时间 ,假设卡门当前体内有足够持续\(10\)小时的能量 ,如果卡门\(10\)小时内没有进食 ,卡门就将饿死 .
输入格式
第一行为\(2\)个整数 ,\(D\)和\(G (1 \le G \le 100)\) , \(G\)为被投入井的垃圾的数量 .
第二到第\(G+1\)行每行包括\(3\)个整数:\(T (0 < T \leq 1000)\) ,表示垃圾被投进井中的时间 : \(F (1 \le F \le 30)\) ,表示该垃圾能维持卡门生命的时间 ;和\(H (1 \le H \le 25)\) ,该垃圾能垫高的高度 .
输出格式
如果卡门可以爬出陷阱 ,输出一个整表示最早什么时候可以爬出 ;否则输出卡门最长可以存活多长时间 .
题解:
为什么神犇们都能看见这道题就想到背包呢 (窝菜得真实
考虑这道题像极了01背包模型 , 井的高度为背包空间 , 存活时间为价值 , 那么\(dp[j]\)表示当前为第\(i\)个垃圾 , 用\(j\)的空间的最大价值 , 也就是高度为\(j\)时的最大生命 (显然生命越大越好) . 但是这题还有一个垃圾落下的时间限制 , 考虑把时间从小到大\(sort\)一遍 , \(dp\)的时候判一下能不能更新 (牛到那个时候还是不是活的) . 在\(dp\)的过程中如果把背包撑爆了直接输出现在的时间就好 (牛已经上去了) , 如果过程中没有撑爆那么说明牛不能在保证不死的前提下上去 , 所以输出背包的最大价值\(dp[0]\) (反正我上不去我就一直苟着垃圾全吃了) .
#include <bits/stdc++.h>
using namespace std;
int d,g;
int dp[105];
struct node{
int t,f,h;
}a[1005];
bool cmp(node x,node y){return x.t<y.t;}
int main(){
scanf("%d%d",&d,&g);
for(int i=1;i<=g;i++) scanf("%d%d%d",&a[i].t,&a[i].f,&a[i].h);
sort(a+1,a+1+g,cmp);
memset(dp,0xcf,sizeof(dp));
dp[0]=10;
for(int i=1;i<=g;i++)
for(int j=d;j>=0;j--){
if(dp[j]>=a[i].t){
if(j+a[i].h>=d){
printf("%d",a[i].t);
return 0;
}
dp[j+a[i].h]=max(dp[j+a[i].h],dp[j]);
dp[j]+=a[i].f;
}
}
printf("%d",dp[0]);
return 0;
}