YCOJ黑熊过河(C++)

嘻嘻,这是一道典型的DP题目,但貌似网上都没有类似的题解,那兔子就来说一说吧!

黑熊过河

描述
有一只黑熊想过河,但河很宽,黑熊不会游泳,只能借助河面上的石墩跳过去,他可以一次跳一墩,也可以一次跳两墩,但是每起跳一次都会耗费一定的能量,黑熊最终可能因能量不够而掉入水中,所幸的事,有些石墩上放了一些食物,这些食物可以给黑熊增加一定的能量,问黑熊能否利用这些石墩安全的抵达对岸,若能,则计算出抵达对岸后剩余能量的最大值是多少?
输入
第一行包含两个整数P(黑熊的初始能量),Q(黑熊每次起跳时耗费的能量),(0≤P,Q≤1000);
第二行只有一个整数N(1≤N≤10^6),即河中石墩的数目;
第三行有N个整数,即每个石墩上食物的能量值ai(0≤ai≤1000)。
输出
输出文件包括一行,若黑熊能抵达对岸,输出抵达对岸后剩余能量的最大值是多少,若不能抵达对岸,则输出“NO”。
输入样例 1
12 5
5
0 5 2 0 7
输出样例 1
6

思路

入手点:
反正就是老一套的动态转移公式和老生常谈的边界问题。
动态转移公式:
我们可以从题目中得到,黑熊可以从a[i-1]与a[i-2]两个方向来,而a[i-1]和a[i-2]又可以从它们的-1或-2个获得。(如图)
YCOJ黑熊过河(C++)_第1张图片
so,所以你想到什么没有?
dp[i]=max(dp[i-1],dp[i-2])-q+a[i];
就是它!
YCOJ黑熊过河(C++)_第2张图片
嘻嘻吗,皮了一波,转移到正题上面

基本框架:

#include
using namespace std;
建立 需要的数据结构;
int main(){
	cin部分;
	for(i:所在河岸下标-对应河岸下标){
		if(要求上次或上上次>0){
			变DP[i]的值
		}
		if(dp[i]没有体力值了){
			dp[i]=极小值
		}
	}
	
	if(不能到对岸){
		cout<<"NO";
		return 0;
	}
	cout<

AC代码

#include
using namespace std;
int p,q,n,a[1000100],dp[1000010];

int main(){
	cin>>p>>q>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}//cin没什么好讲的
	
	dp[0]=p;//下标0是所在河岸,n+1是对岸
	dp[1]=p-q>=0 ? p-q+a[1] : -0x7f7f7f7f ;//我们对dp[0]、dp[1]预处理
	for(int i=2;i<=n+1;i++){//0,1下标已经处理,所以从2开始
		bool flag=0;//判断是否dp[i]的获得点为熊跳不过,若没有改变初值则两点都跳不到dp[i]
		if(dp[i-1]-q>=0){//从dp[i-1]到达
			flag=1;
			dp[i] =max(dp[i], dp[i-1]-q+a[i]);
		}
		if(dp[i-2]-q>=0){//从dp[i-2]到达
			flag=1;
			dp[i]=max(dp[i], dp[i-2]-q+a[i]);
		}
		if(!flag){//跳不到dp[i]
				dp[i]=-0x7f7f7f7f;
		}
	}
	
	if(dp[n+1]<0){
		cout<<"NO";
		return 0;
	}
	
	cout<

本期题解就到这里,希望小伙伴们点个关注,下期我们再会,233333333~拜啦!!在这里插入图片描述

你可能感兴趣的:(YCOJ的日常水题题解)