【解题报告】 垃圾陷阱

这道题是一道非常典型的DP,下面我们就来对这道题进行一些讲解!

题目链接:
P1156 垃圾陷阱

作为一道“提高+/省选-”的题目,相信这道题还是很有价值的,本题的价值就在“时间”这个限制变量上,这个变量要是没有看出来,那么这道题想要AC确实就有一点困难了!!!

解题方法:

本题鄙人用的是滚动数组的办法,很偷懒,有一点耍小聪明的感觉,但是这种方法却也是最好的!

如果你还没有看通“时间”这一限制变量的话,下面这一段话请仔细斟酌后在阅读

时间这个变量说实话是并没有什么实际用处的,他只是用来限制是否当前奶牛有能力撑过从头开始一直到现在将要度过的一长段时间(这句话看不懂其实也没有什么太大的关系!等会儿看代码你一定是会懂的!)所以说时间这个东西,自始至终你都不需要在奶牛所有能量上减去时间上所耗费的能量!

下面是动态转移方程式:

伪代码:

if(奶牛当前的体力能够承受将要等待的时间)
{
    垫高后奶牛的能量=max(当前位置的能量,和垫高后之前奶牛的能量);
    奶牛的能量+=垃圾的能量;
}

相信大家已经懂了!

下面直接上源代码吧:(代码中的变量自带注释功能!)

#include
using namespace std;
int deep,n;
int bag[5005];
struct sd{
    int time,energy,height;
}rubbish[1005];
bool cmp(sd a,sd b)
{
    if(a.time>=b.time) return false;//为虾米这里一定要加一个等号啊? 
    return true;
}
int main()
{
    scanf("%d%d",&deep,&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%d%d%d",&rubbish[i].time,&rubbish[i].energy,&rubbish[i].height);
    }
    sort(rubbish+1,rubbish+1+n,cmp);
    bag[0]=10;
    for(int i=1;i<=n;++i)
    {
        for(int j=deep;j>=0;--j)
        {
            if(rubbish[i].time<=bag[j])
            {
                if(j+rubbish[i].height>=deep)
                {
                    printf("%d",rubbish[i].time);
                    return 0;
                }
                bag[j+rubbish[i].height]=max(bag[j+rubbish[i].height],bag[j]);
                bag[j]+=rubbish[i].energy;
            }
        }
    }
    printf("%d",bag[0]);
    return 0;
}

虽然这个方法看似比较高端,但是我们也要掌握一些看上去稍微低端一些的方法,那就是用二维数组,因为这玩意儿我也没有写过,所以这里为大家链接一篇博客就可以了:

(大家上面的代码都看的懂,相信二维数组就是小case了!!)

垃圾陷阱【二维数组办法】!

P.s:这里有人看完链接中的方法后可能会问,为什么二维数组中可以正着循环,而滚动数组中只能倒着循环?这是因为背包问题都是倒着处理的(害怕有重复!)但是倒着的地方有一些区别,二维数组是在里面倒着的,而滚动数组是在循环的时候进行倒着处理的,相信大家应该都懂了吧!

这里同时感谢看了本篇解题报告的人,在这里为某些懒人who is not willing to learn someting from the second problem solution!放上第二种思路的状态转移方程式部分:(不用谢我!)

    if (f[i-1][j]-a[i].x+a[i-1].x>=0) 
            {
                f[i][j]=max(f[i][j],f[i-1][j]-a[i].x+a[i-1].x+a[i].t);//一定要判断一下时间允不允许!
            }
            if (f[i-1][j-a[i].h]-a[i].x+a[i-1].x>=0&&j-a[i].h>=0) 
            {
                f[i][j]=max(f[i][j],f[i-1][j-a[i].h]-a[i].x+a[i-1].x);
                if (j==n)
                {
                    printf("%d\n",a[i].x);
                    fl=1;
                    return 0;

你可能感兴趣的:(解题报告,动态规划)