洛谷P1156 垃圾陷阱
? 解题记录 ? ? 洛谷 ? ? 动态规划 ?    2017-10-06 14:24:09    456    0    0

题目描述

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

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

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

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

输入输出格式

输入格式:

 

第一行为2个整数,D 和 G (1 <= G <= 100),G为被投入井的垃圾的数量。

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

 

输出格式:

 

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

 

输入输出样例

输入样例#1:
20 4
5 4 9
9 3 2
12 6 10
13 1 1
输出样例#1:
13

说明

[样例说明]

卡门堆放她收到的第一个垃圾:height=9;

卡门吃掉她收到的第二个垃圾,使她的生命从10小时延伸到13小时;

卡门堆放第3个垃圾,height=19;

卡门堆放第4个垃圾,height=20。

首先,考虑到节约空间并且便于转移,我们用dp[i][j]表示到了第i个垃圾的时候,高度为j,生命值最大是多少。那么很显然状态转移方程就应该有2种情况:1、吃了当前块。2、没有吃当前块。转移的条件就应该是奶牛能活过i、i-1两个物品间的间隔。注意到我们要对j为0~井深的所有状态进行转移。另外,这道题刷表比填表好写的多,建议刷表。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 2e3 + 5;
int dp[maxn][105], n, d, ans;
struct item {
    int food, h, time;
    bool operator <(const item &a) const {return time < a.time;}
}items[105];
signed main() {
    scanf("%d%d", &d, &n);
    memset(dp, 0xc0, sizeof(dp));
    for(register int i = 1; i <= n; ++i) 
        scanf("%d%d%d", &items[i].time, &items[i].food, &items[i].h);
    sort(items + 1, items + 1 + n);
    dp[0][0] = 10;
    for(register int i = 1; i <= n; ++i) {
        for(register int j = 0; j <= d; ++j) {
            if(dp[i - 1][j] < items[i].time - items[i - 1].time) continue;
            if(j + items[i].h >= d) {
                printf("%d", items[i].time);
                return 0;
            }
            if(dp[i][j] < dp[i - 1][j] + items[i].food - (items[i].time - items[i - 1].time))
            dp[i][j] = dp[i - 1][j] + items[i].food - (items[i].time - items[i - 1].time);
            if(dp[i][j + items[i].h] < dp[i - 1][j] - (items[i].time - items[i - 1].time))
            dp[i][j + items[i].h] = dp[i - 1][j] - (items[i].time - items[i - 1].time);    
        }
        if(ans < dp[i][0] + items[i].time) ans = dp[i][0] + items[i].time;
    }
    printf("%d", ans);
    return 0;
}

 

上一篇: 洛谷P1040 加分二叉树

下一篇: 洛谷P1273 有线电视网

456 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航