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