洛谷Oj-垃圾陷阱-背包

来源:互联网 发布:二叉树的遍历算法c 编辑:程序博客网 时间:2024/05/18 16:37

问题描述:
卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2<=D<=100)英尺。
卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。
每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。
假设卡门预先知道了每个垃圾扔下的时间t(0< t<=1000),以及每个垃圾堆放的高度h(1<=h<=25)和吃进该垃圾能维持生命的时间f(1<=f<=30),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续10小时的能量,如果卡门10小时内没有进食,卡门就将饿死。
AC代码:

int dp[110][110];//dp[i][j]表示使用前i个垃圾且垃圾的高度为j时的最大生命值struct trash//垃圾{    int t;//被抛进垃圾井的时间    int f;//续命量    int h;//高度};trash gar[110];bool cmp(const trash &a,const trash &b)//由被抛进垃圾井的时间升序排列{    return a.t < b.t;}int main(){    int d,g;    //输入    cin >> d >> g;    for(int i = 1; i <= g; ++i)        scanf("%d%d%d",&gar[i].t,&gar[i].f,&gar[i].h);    sort(gar + 1,gar + g + 1,cmp);//排序    memset(dp,-1,sizeof(dp));//初始化为一个不可能值,如-1    dp[0][0] = 10;//边界,一开始有10小时的生命    for(int i = 1; i <= g; ++i)        for(int j = 0;j <= d; ++j)        {            //牛必须存活,才能吃到垃圾。即判断从dp[i - 1][j]状态出发,消耗(gar[i].t - gar[i - 1].t)的时间后牛是否还活着(生命值大于0)            if(dp[i - 1][j] - (gar[i].t - gar[i - 1].t) >= 0)//否则不转移!!!                dp[i][j] = max(dp[i][j],dp[i - 1][j] - (gar[i].t - gar[i - 1].t) + gar[i].f);//吃垃圾            //如果牛在第i个垃圾到达时存活且之前的高度大于等于0            if(dp[i - 1][j - gar[i].h] - (gar[i].t - gar[i - 1].t) >= 0 && j - gar[i].h >= 0)            {                dp[i][j] = max(dp[i][j],dp[i - 1][j - gar[i].h] - (gar[i].t - gar[i - 1].t));//堆垃圾                if(j == d)//如果到达指定高度                {                    printf("%d\n",gar[i].t);//输出此时的时间                    return 0;//返回                }            }        }    int ans = -inf;    for(int i = 0; i <= g; ++i)        for(int j = 0;j <= d; ++j)            if(dp[i][j] != -1)//从能到达的状态中找到最大值                ans = max(ans,gar[i].t + dp[i][j]);//已经消耗的生命值加上还有的生命值    cout << ans << endl;    return 0;}

解决方法:
我们可以通过生命值,垃圾堆的高度,使用了前i件垃圾来确定当前的状态
而使用了前i个垃圾,就是背包问题中的描述,所以将问题转化为背包问题
题目既问了最早什么时候可以爬出,又问了最长可以存活多长时间。
到底将哪个值作为dp[i][j]的值呢?
一定要注意不能访问负下标,所以要加上判断条件
将数组初始化为-1,表示状态无法到达
做出决策的时候要考虑前提条件,比如此时牛是否还活着
消耗的生命值用等待下一个垃圾落下的时间计算gar[i].t - gar[i - 1].t

原创粉丝点击