【動態規划】黑熊過河


題目描述

晶晶的爸爸給晶晶出了一道難題:有一只黑熊想過河,但河很寬,黑熊不會游泳,只能借助河面上的石墩跳過去,它可以一次跳一墩,也可以一次跳兩墩,但是每跳一次都會耗費一定的能量,黑熊最終可能因能量不夠而掉入水中。所幸的是,有些石墩上放了一些食物,這些食物可以給黑熊增加一定的能量。問黑熊能否利用這些石墩安全地抵達對岸?請計算出抵達對岸后剩余能量的最大值。

 

輸入

第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 等等


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM