• 【动态规划】黑熊过河


    题目描述

    晶晶的爸爸给晶晶出了一道难题:有一只黑熊想过河,但河很宽,黑熊不会游泳,只能借助河面上的石墩跳过去,它可以一次跳一墩,也可以一次跳两墩,但是每跳一次都会耗费一定的能量,黑熊最终可能因能量不够而掉入水中。所幸的是,有些石墩上放了一些食物,这些食物可以给黑熊增加一定的能量。问黑熊能否利用这些石墩安全地抵达对岸?请计算出抵达对岸后剩余能量的最大值。

    输入

    第1行包含两个整数P(黑熊的初始能量),Q(黑熊每次起跳时耗费的能量),0≤P,Q≤1000;
    第2行只有一个整数n(1≤n≤106),即河中石墩的数目;
    第3行有n个整数,即每个石墩上食物的能量值ai(0≤ai≤1000)。

    输出

    仅1行,若黑熊能抵达对岸,输出抵达对岸后剩余能量的最大值;若不能,则输出“NO”。

    样例输入

    12 5
    5
    0 5 2 0 7
    

    样例输出

    6



    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main()
    {
        int p,q;
        int n;
        int a[100015];
        cin>>p>>q;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        int dp[100015];
        bool vis[100015];
        memset(dp,0,sizeof(dp));
        memset(vis,false,sizeof(vis));
        if(p<q)
        {
            cout<<"NO";
            return 0;
        }
        vis[0] = true;
        dp[0] = p;
        dp[1] = dp[0]-q+a[1];
        if(dp[1]<q)
        {
            vis[1] = false;
        }
        else
        {
            vis[1] = true;
        }
        for(int i=2;i<=n;i++)
        {
            if(!vis[i-1]&&!vis[i-2])
            {
                cout<<"NO";
                return 0;
            }
            if(vis[i-1]==false&&vis[i-2]==true)
            {
                dp[i] = dp[i-2]-q+a[i];
            }
            else if(vis[i-1]==true&&vis[i-2]==false)
            {
                dp[i] = dp[i-1]-q+a[i];
            }
            else
            {
                dp[i] = max(dp[i-1]-q+a[i],dp[i-2]-q+a[i]);
            }
            if(dp[i]>=q)
                vis[i] = true;
        }
    
        if(vis[n]==true&&vis[n-1]==false)
        {
            cout<<dp[n]-q;
            return 0;
        }
        else if(vis[n]==false&&vis[n-1]==true)
        {
            cout<<dp[n-1]-q;
        }
        else if(vis[n]==true&&vis[n-1]==true)
        {
            cout<<max(dp[n]-q,dp[n-1]-q);
        }
        else
        {
            cout<<"NO";
        }
        return 0;
    }

    vis[]记录了该点能否到达           

    一个点到达当前状态 无非就是从这个点前两个点中的一个来的      

    而如果vis【i-1】和vis【i-2】都是false那么熊的能量已经耗尽 之后也无法到达   输出NO

    其中有几个重要的特判和初始化操作

    如开始dp【0】 = 初始值p

    特判初始值p<q 等等

  • 相关阅读:
    给JFinal添加 Sqlite 数据库支持
    超强、超详细Redis数据库入门教程
    HTML5实现多文件的上传示例代码
    JAVA 使用Dom4j 解析XML
    【VBA研究】Excel VBA利用ADODB访问数据库使用小结
    JFinal 部署在 Tomcat 下推荐方法
    Java WebService 简单实例
    关于XML的验证(DTD与XSD)一点实践
    基于机器学习的web异常检测
    30万奖金!还带你奔赴加拿大相约KDD!?阿里聚安全算法挑战赛带你飞起!
  • 原文地址:https://www.cnblogs.com/hao-tian/p/9388159.html
Copyright © 2020-2023  润新知