P1156 垃圾陷阱

Posted garen-wang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1156 垃圾陷阱相关的知识,希望对你有一定的参考价值。

我是真的不知道。。。

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

终止条件是堆放的高度达到(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
", 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
", ans);
    return 0;
}

以上是关于P1156 垃圾陷阱的主要内容,如果未能解决你的问题,请参考以下文章

[luogu]P1156 垃圾陷阱[DP]

洛谷 P1156 垃圾陷阱

Luogu P1156 垃圾陷阱

P1156 垃圾陷阱

P1156 垃圾陷阱

洛谷 P1156 垃圾陷阱