题目
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。
解题思路
动态规划
- f(n)表示到达第n个台阶花费的总体力
- 可以从下标0或者下标1的位置出发,初始化:
- 从下标0出发:dp[0] = cost[0]
- 从下标1出发:dp[1] = cost[1]
- 状态转移方程:f(n) = min{f(n-1),f(n-2)} + cost[n]
- 到达楼层顶部:
- 到达倒数第二个台阶(可以跨越2个台阶越过顶层台阶),总共花费体力为f[last-1]
- 到达顶层台阶,总共花费体力为f[last]
- 选取min{f[last-1],f[last]}作为最优方案
代码
class Solution {
public int minCostClimbingStairs(int[] cost) {
int len = cost.length;
int[] dp = new int[len];
// 从下标为0的元素出发
dp[0] = cost[0];
// 从下标为1的元素出发
dp[1] = cost[1];
// 状态转移方程:f(n) = min{f(n-1),f(n-2)} + cost[n]
for (int i = 2; i < len; i++) dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
// 到达楼层顶部:
// 1. 到达倒数第二个台阶(可以跨越2个台阶越过顶层台阶),总共花费体力为f[last-1]
// 2. 到达顶层台阶,总共花费体力为f[last]
// 3. 选取min{f[last-1],f[last]}作为最优方案
return Math.min(dp[len - 2], dp[len - 1]);
}
}
使用滚动数组优化空间
class Solution {
public int minCostClimbingStairs(int[] cost) {
int p = cost[0], q = cost[1];
// 状态转移方程:f(n) = min{f(n-1),f(n-2)} + cost[n]
for (int i = 2; i < cost.length; i++) {
int tmp = Math.min(p, q) + cost[i];
p = q;
q = tmp;
}
return Math.min(p, q);
}
}