【洛谷】P1156 垃圾陷阱 解题报告

【洛谷】P1156 垃圾陷阱 解题报告

题目描述

卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D≤100)英尺。

卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。

每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。

假设卡门预先知道了每个垃圾扔下的时间t(0< t \le 1000)t(0

输入输出格式

输入格式:

第一行为22个整数,D D和 G (1 \le G \le 100)G(1≤G≤100),GG为被投入井的垃圾的数量。

第二到第G+1G+1行每行包括33个整数:T (0 < T <= 1000)T(0

输出格式:

如果卡门可以爬出陷阱,输出一个整表示最早什么时候可以爬出;否则输出卡门最长可以存活多长时间。

输入输出样例

input

20 4
5 4 9
9 3 2
12 6 10
13 1 1

output

13

思路

对于每个辣鸡,吃还是不吃,吃了就可以+HP,不吃就可以加高度,而我们最终要求的是是否能出去,所以可以设f[当前高度]=当前生命值。
然后这道DP可以用一种叫刷表法的方法来做。
即用已知的当前状态去更新未知状态。
这样一想就十分简单了
对于每个辣鸡,吃还是不吃,
吃了

f[j+r[i].hight]=max(f[j+r[i].hight],f[j]);

没吃

           f[j]+=r[i].health;

如果当前高度大于深度,并且生命值>0,那就直接输出啦
如果GG了,那就输出高度为为0的生命值。

Code

#include
using namespace std;
#define maxn 105

int n,D;
int f[maxn*100];
struct Rub
{
    int t,health,hight;
}r[maxn];

bool cmp(Rub a,Rub b)
{
    return a.t < b.t;
}

int main()
{
    scanf("%d%d",&D,&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d%d",&r[i].t,&r[i].health,&r[i].hight);
    sort(r+1,r+1+n,cmp);
    f[0]=10;
    for(int i=1;i<=n;i++)
        for(int j=D;j>=0;j--)
            if(f[j] >= r[i].t)
            {
                if(j+r[i].hight>=D)
                {
                    printf("%d\n",r[i].t);
                    return 0;
                }
                f[j+r[i].hight]=max(f[j+r[i].hight],f[j]);
                f[j]+=r[i].health;
            }
    printf("%d\n",f[0]);
    return 0;
}

你可能感兴趣的:(线性DP,一些比较妙的题)