码迷,mamicode.com
首页 > 其他好文 > 详细

P1156 垃圾陷阱

时间:2018-09-17 00:07:24      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:std   转移   inf   i++   ||   初始化   getc   char   时间   

我是真的不知道。。。

这道题对于每一个垃圾有两个决策:堆放不吃 或者 吃掉不堆放。

终止条件是堆放的高度达到\(d\)。想要求达到状态的最大生命值或者最久能活到多久。

可以联想到背包问题,而且是01背包。

把生命值当做价值,把高度当做重量,我们就可以用最小重量取出最大价值。

\(dp[i][j]\)为前\(i\)个垃圾,已经堆放了高度\(j\)的最大生命值。

递推就可以想普通的填表法搞出来。

这个东西挺奇怪的,奶牛生命值为0的时候还能转移。。。这个注意一下。

如果填表的时候填到\(j==n\)的时候就可以判断是可以出去的,直接return掉。

否则要输出奶牛能活最久多长时间。我们可以利用dp数组,求出的最大生命值加上那一块掉落时间。

注意:在做dp的时候,有的dp是没有状态的,是会死的。这些死的dp值是负数。

所以我们要初始化dp数组为负无穷大。

注意:给你的垃圾顺序可能是乱序的,要按照时间顺序排序。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>

const int maxn = 105;
const int INF = 0x3f3f3f3f;

int d, g;
struct Trash
{
    int tim, t, h;
} s[maxn];
int dp[maxn][maxn];
// 前i件垃圾,堆了高度j的最大生命值 
int read()
{
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > ‘9‘ || ch < ‘0‘)
    {
        if(ch == ‘-‘) s = -1;
        ch = getchar();
    }
    while(ch >= ‘0‘ && ch <= ‘9‘) ans = (ans << 3) + (ans << 1) + ch - ‘0‘, ch = getchar();
    return s * ans;
}
bool cmp(const Trash a, const Trash b)
{
    return a.tim < b.tim;
}
int main()
{
    d = read(), g = read();
    for(int i = 1; i <= g; i++)
    {
        s[i].tim = read(), s[i].t = read(), s[i].h = read();
    }
    for(int i = 0; i <= g; i++) for(int j = 0; j <= d; j++) dp[i][j] = -INF;
    std::sort(s + 1, s + g + 1, cmp);
    dp[0][0] = 10;
    for(int i = 1; i <= g; i++)
    {
        for(int j = 0; j <= d; j++)
        {
            
            if(dp[i - 1][j] - (s[i].tim - s[i - 1].tim) >= 0)// 没被饿死 
            {
                dp[i][j] = std::max(dp[i][j], dp[i - 1][j] - (s[i].tim - s[i - 1].tim) + s[i].t);
            }
            if(dp[i - 1][j - s[i].h] - (s[i].tim - s[i - 1].tim) >= 0 && j - s[i].h >= 0)// 没被饿死,并且能转移 
            {
                dp[i][j] = std::max(dp[i][j], dp[i - 1][j - s[i].h] - (s[i].tim - s[i - 1].tim));
                if(j == d)
                {
                    printf("%d\n", s[i].tim);
                    return 0;
                }
            }
        }
    }
    int ans = -INF;
    for(int i = 1; i <= g; i++)
    {
        for(int j = 0; j <= d; j++)
        {
            if(dp[i][j] < 0) continue;
            ans = std::max(ans, dp[i][j] + s[i].tim);
        }
    }
    printf("%d\n", ans);
    return 0;
}

P1156 垃圾陷阱

标签:std   转移   inf   i++   ||   初始化   getc   char   时间   

原文地址:https://www.cnblogs.com/Garen-Wang/p/9658038.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!