蓝桥杯-秘密行动

秘密行动

资源限制

内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s

问题描述

小D接到一项任务,要求他爬到一座 n n n 层大厦的顶端与神秘人物会面。这座大厦有一个神奇的特点,每层的高度都不一样,同时,小D也拥有一项特殊能力,可以一次向上跳跃一层或两层,但是这项能力无法连续使用。已知向上1高度消耗的时间为1,跳跃不消耗时间。由于事态紧急,小D想知道他最少需要多少时间到达顶层。

输入格式

第一行包含一个整数 n n n,代表楼的高度。

接下来n行每行一个整数 a i ai ai,代表i层的楼层高度( a i ai ai <= 100)。

输出格式

输出1行,包含一个整数,表示所需的最短时间。
样例输入

5
3
5
1
8
4

样例输出

1

数据规模和约定

对20%的数据, n n n<=10
对40%的数据, n n n<=100
对60%的数据, n n n<=5000
对100%的数据, n n n<=10000

题解

动态规划的经典题型。本题的题目稍微有些脱离现实,因为从生活角度来说,到达第一层应该不需要爬楼梯或跳跃,本题的意思接近于:到达第n层的楼顶所需要的最短时间。

对于到达每一层,都具有两个状态,一个是爬上来的,一个是跳跃上来的。

  • 如果第 i i i 层是爬上来的,那么就是从第 i − 1 i-1 i1 层爬上来的,至于如何到达的第 i − 1 i-1 i1 层,无所谓,因为跳跃不能连续,但是爬楼梯可以连续。那么最短时间就是到达第 i − 1 i-1 i1 层的最短时间+第 i i i 层的高度。
  • 如果第 i i i 层是跳上来的,那么就是从第 i − 1 i-1 i1 层或第 i − 2 i-2 i2 层跳上来的,但是到达第 i − 1 i-1 i1 层或第 i − 2 i-2 i2 层一定是爬楼梯上来的。最短时间就是爬楼梯上到第 i − 1 i-1 i1 层或第 i − 2 i-2 i2 层的最小值。

状态转移方程
d p [ 0 ] [ i ] = m i n ( d p [ 0 ] [ i − 1 ] + h e i g h t [ i ] , d p [ 1 ] [ i − 1 ] + h e i g h t [ i ] d p [ 1 ] [ i ] = m i n ( d p [ 0 ] [ i − 1 ] , d p [ 0 ] [ i − 2 ] ) \begin{aligned} dp[0][i] &= min(dp[0][i-1]+height[i], dp[1][i-1] + height[i]\\ dp[1][i] &= min(dp[0][i-1],dp[0][i-2]) \end{aligned} dp[0][i]dp[1][i]=min(dp[0][i1]+height[i],dp[1][i1]+height[i]=min(dp[0][i1],dp[0][i2])
初始状态
d p [ 0 ] [ 1 ] = h e i g h t [ 1 ] d p [ 1 ] [ 1 ] = 0 d p [ 0 ] [ 2 ] = m i n ( d p [ 1 ] [ 1 ] + h e i g h t [ 2 ] , d p [ 0 ] [ 1 ] + h e i g h t [ 2 ] ) d p [ 1 ] [ 2 ] = m i n ( d p [ 0 ] [ 1 ] , d p [ 0 ] [ 0 ] ) \begin{aligned} dp[0][1] &= height[1]\\ dp[1][1] &= 0\\ dp[0][2] &= min(dp[1][1]+height[2], dp[0][1] + height[2])\\ dp[1][2] &= min(dp[0][1], dp[0][0]) \end{aligned} dp[0][1]dp[1][1]dp[0][2]dp[1][2]=height[1]=0=min(dp[1][1]+height[2],dp[0][1]+height[2])=min(dp[0][1],dp[0][0])
代码

n = int(input())
height = [0 for i in range(n+1)]
for i in range(1,n+1):
	height[i] = int(input())
if n <= 2:
	print(0)
else:	
	dp = [[0]*(n+1) for i in range(2)]
	# dp[0][x]表示到达第x层是爬着
	# dp[1][x]表示达到第x层是跳跃
	dp[0][1] = height[1]
	dp[1][1] = 0
	dp[0][2] = min(dp[1][1]+height[2], dp[0][1] + height[2])
	dp[1][2] = min(dp[0][1], dp[0][0])

	for i in range(2, n+1):
		dp[0][i] = min(dp[0][i-1]+height[i], dp[1][i-1] + height[i])
		dp[1][i] = min(dp[0][i-1],dp[0][i-2])
	print(min(dp[0][n], dp[1][n]))

猜你喜欢

转载自blog.csdn.net/BWQ2019/article/details/123968793