1. 初级爬台阶 – 求最短步数
LC – 70
一次可以迈1-2个台阶,因此最短步数与前两个台阶有关。
Initial state: 第一阶:1步 ; 第二阶:1步
deduction function: f[n] = f[n – 1] + f[n – 2];
====可以推出,第三阶可以从第一阶迈出,可以从第二阶迈出,因此有两种可能。基本就是斐波那契数列求和。
public int climbStairs(int n) {
if(n == 0) return 1;
if(n == 1) return 1; int[] dp = new int[n];
dp[0] = 1;
dp[1] = 2; for(int i = 0 ; i < n - 2 ; i++){
dp[i + 2] = dp[i] + dp[i + 1];
} return dp[n - 1];
}
2. 求最短开销
LC – 746
每个台阶的cost不同,还是只能迈1-2个台阶,这回求到顶点的最小开销。
Initial state: 2个台阶以内最小开销为cost[0], cost[1]中的最小值。0->1->dist or 0->2->dist
deduction function: f[n] = Math.min(dp[n – 1], dp[n – 2]) + cost[n]
====> 因为可以从n-1阶跳,也可以从n-2阶跳,选开销最小的台阶。
====>注意:可以从n->dist,n-1->dist,两个点都是有效的,因此结果选两个点中最小的。
public int minCostClimbingStairs(int[] cost) {
int len = cost.length;
if(len == 0) return cost[0];
if(len == 1) return Math.min(cost[0], cost[1]); int[] dp = new int[len]; dp[0] = cost[0];
dp[1] = cost[1]; for(int i = 2 ; i < len ; i++){
dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
} return Math.min(dp[len - 1], dp[len - 2]);
}
3. 1的进阶版
步数是2的幂。求有多少种组合。
因此:f[n] = f[n – 1] + f[n – 2] + f[n – 4] + … + f[1]
public static int countSteps(int n) {
int[] dp = new int[n + 1];
dp[0] = 1; for(int i = 0 ; i < n ; i++) {
if(i == 0 || i == 1) dp[i + 1] = i + 1;
else {
int j = 0, tmp = 0;
while(Math.pow(2, j) <= i + 1) {
tmp += dp[(int) (i + 1 - Math.pow(2, j))];
j++;
}
dp[i + 1] = tmp;
}
}
System.out.println(Arrays.toString(dp));
return dp[n];
}
莽就对了。。。