p1156 题解(未完全解决)
题目描述
卡门――农夫约翰极其珍视的一条Holsteins
奶牛――已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D≤100)英尺。
卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。
每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。
假设卡门预先知道了每个垃圾扔下的时间t(0< t \le 1000)t(0<t≤1000),以及每个垃圾堆放的高度h(1 \le h \le 25h(1≤h≤25)和吃进该垃圾能维持生命的时间f(1 \le f \le 30)f(1≤f≤30),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续1010小时的能量,如果卡门1010小时内没有进食,卡门就将饿死。
输入输出格式
输入格式:
第一行为22个整数,DD和 G (1 \le G \le 100)G(1≤G≤100),GG为被投入井的垃圾的数量。
第二到第G+1G+1行每行包括33个整数:T (0 < T <= 1000)T(0<T<=1000),表示垃圾被投进井中的时间;F (1 \le F \le 30)F(1≤F≤30),表示该垃圾能维持卡门生命的时间;和 H (1 \le H \le 25)H(1≤H≤25),该垃圾能垫高的高度。
输出格式:
如果卡门可以爬出陷阱,输出一个整表示最早什么时候可以爬出;否则输出卡门最长可以存活多长时间。
输入输出样例
20 4 5 4 9 9 3 2 12 6 10 13 1 1
13
如果卡门可以爬出陷阱,输出一个整表示最早什么时候可以爬出;否则输出卡门最长可以存活多长时间。
dp实锤。(走出门,就与dp撞了个满怀,题面里含着背包的气息,夜里,好清爽!)
经过一通胡思乱想,我觉得状态应该是血量。(事实证明确实是血量)
然后好像就比较明朗了。
直接枚举当前高度的血量。但是方程好像有点迷、、、
枚举高度(i),枚举n(j)。dp[i]表视当前高度的血量。
dp[垫一个草块]=max(dp[扔下来一个草块吃],dp[扔下来一个草块不吃,垫])
划重点!!!!!!!!!!!!!!!!
dp[i]+=e[i].f;
这是我没有想到的(虽然后来看也就是这么回事)
坑点:
1、输入不按照时间顺序,所以要排序。
2、当dp[i]=0时,奶牛处于濒死状态,所以要初始化-1
未解决的问题:
1、为何j的枚举要倒序?
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=10005; int dp[maxn];//i=height;dp[i]=life int n,m; int maxm; struct node { int t,f,h; }e[maxn]; bool cmp(node a,node b) { return a.t<b.t; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&e[i].t,&e[i].f,&e[i].h); } sort(e+1,e+m+1,cmp); memset(dp,-1,sizeof(dp)); dp[0]=10; for(int i=1;i<=m;i++) { for(int j=n;j>=0;j--) { if(dp[j]>=e[i].t) { if(j+e[i].h>=n) { printf("%d",e[i].t); return 0; } dp[j+e[i].h]=max(dp[j],dp[j+e[i].h]); dp[j]+=e[i].f; } } } //for(int i=1;i<=n;i++) printf("%d",dp[0]); return 0; }