数组的每个索引作为一个阶梯,第 i个阶梯对应着一个非负数的体力花费值 costi。
每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。
您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索引为 0 或 1 的元素作为初始阶梯。
示例 1:
输入: cost = [10, 15, 20]
输出: 15
解释: 最低花费是从cost[1]开始,然后走两步即可到阶梯顶,一共花费15。
示例 2:
输入: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
输出: 6
解释: 最低花费方式是从cost[0]开始,逐个经过那些1,跳过cost[3],一共花费6。
对于每一个台阶,从底部到达其位置时所消耗的体力都必须是最少的
换句话说,每一个台阶都可以作为一“顶层台阶”
每层楼梯对应不同的阶段,具体映射为k=cost列表索引
与楼梯k有关的初始变量为cost值,但我们需要的x(k)是到达k阶楼梯到最优解
决策变量应该与与楼梯k有关的初始变量有关(这个“有关”在一定程度上保证了无后效性)
事实上,u(k)=cost
既然已经判断出问题具有最优子结构性质,那也不难看出x(k)等于x(k-2)+cost[k-2]与x(k-1)+cost[k-1]中较小的那一个
即:
x(k)=min(x(k-2)+cost[k-2], x(k-1)+cost[k-1])
由于可以选择下标 0或1 作为初始阶梯,因此有
x(0)=x(1)=0
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
n = len(cost)
x = [0]*(n+1)
for k in range(2,n+1):
x[k]=min(x(k-2)+cost[k-2], x(k-1)+cost[k-1])
return x[n]
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
n = len(cost)
x = [0]*(n+1)
for k in range(2,n+1):
x[k]=min(x(k-2)+cost[k-2], x(k-1)+cost[k-1])
return x[n]
遍历cost
x列表长n+1
通过滚动列表优化空间复杂度
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
n = len(cost)
prev = curr = 0
for i in range(2, n + 1):
nxt = min(curr + cost[i - 1], prev + cost[i - 2])
prev, curr = curr, nxt
return curr
动态规划模版链接