p1156 题解(未完全解决)

题目描述

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

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

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

假设卡门预先知道了每个垃圾扔下的时间t(0< t le 1000)t(0<t1000),以及每个垃圾堆放的高度h(1 le h le 25h(1h25)和吃进该垃圾能维持生命的时间f(1 le f le 30)f(1f30),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续1010小时的能量,如果卡门1010小时内没有进食,卡门就将饿死。

输入输出格式

输入格式:

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

第二到第G+1G+1行每行包括33个整数:T (0 < T <= 1000)T(0<T<=1000),表示垃圾被投进井中的时间;F (1 le F le 30)F(1F30),表示该垃圾能维持卡门生命的时间;和 H (1 le H le 25)H(1H25),该垃圾能垫高的高度。

输出格式:

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

输入输出样例

输入样例#1: 复制
20 4
5 4 9
9 3 2
12 6 10
13 1 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;
}

原文地址:https://www.cnblogs.com/ajmddzp/p/11026045.html