import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param cost int整型一维数组
* @return int整型
*/
public int minCostClimbingStairs (int[] costs) {
// write code here
// 算法核心:从【递归回溯尝试】优化到【记忆化搜素】(因为装填转移只有2个,因此效率与动态规划类似)
// dp表默认初始化全-1
int[] dp = new int[costs.length + 1];
for (int i = 0; i < dp.length; i++) {
dp[i] = -1;
}
// 注意,爬到数组刚好越界才算爬完
int result = process(costs, costs.length, dp);
return result;
}
// 计算爬到第target阶(0开始)的最小花费
public int process (int[] costs, int target, int[] dp) {
// 递归出口
if (target == 0) {
// 爬到第0阶台阶的最小花费
// 为0,因为可以直接从0开始爬
dp[0] = 0;
return dp[0];
}
if (target == 1) {
// 爬到第1阶台阶的最小花费
// 为0,因为可以直接从1开始爬
dp[1] = 0;
return dp[1];
}
// 分支尝试
// 本题状态的转移是【有限个】的,即【不依赖for循环】列举进行状态转移
// 因此,【记忆化搜索】与【经典动态规划】的时间复杂度【近似】
// 如果dp表中有计算好的值,则可直接返回
if (dp[target] != -1) {
return dp[target];
}
// 上了一个台阶到达target位置
if (dp[target - 1] == -1) {
// dp表中无值
dp[target - 1] = process(costs, target - 1, dp);
}
int one = dp[target - 1] + costs[target - 1];
// 上了两个台阶到达target位置
if (dp[target - 2] == -1) {
// dp表中无值
dp[target - 2] = process(costs, target - 2, dp);
}
int two = dp[target - 2] + costs[target - 2];
// 记录本位置dp值
dp[target] = Math.min(one, two);
return dp[target];
}
}