輸入:一個數組cost,cost[i]表示越過第i個臺階的代價(可能是熱量,也可能是過路費)
輸出:走過這n個臺階,需要的最小代價
規則:一旦你爲第i個臺階付出代價cost[i],那麼你可以到達第i+1個臺階,也可以到達第i+2個臺階。你可以從第0個或者第1個臺階開始走。
分析:沒什麼好說的,一步步走,沒走一步付出代價private void walk(int step,int currentcost) 表達站在第i個臺階,付出了多少代價。
你可以試着把cache去掉,當然是超時。加cache是因爲,如果你曾經花費代價10站在了第5個臺階,那下次遇到需要花費代價15站在了第5個臺階,就沒必要進行走下去。因爲代價肯定高嘛。
class Solution {
private int mincost = Integer.MAX_VALUE;
private int[] cost;
private int[] cache;
private int n;
public int minCostClimbingStairs(int[] cost) {
this.cost = cost;
this.n = cost.length;
this.cache = new int[n];
walk(0,0);
walk(1,0);
return mincost;
}
private void walk(int step,int currentcost){
if(step>=n){
mincost = Math.min(mincost,currentcost);
return;
}
if(cache[step]==0 || currentcost<cache[step]){
cache[step] = currentcost;
walk(step+1,currentcost+cost[step]);
walk(step+2,currentcost+cost[step]);
}
}
}
動態規劃分析:初步分析得到能站點第i個臺階的代價應該是與第i-1和第i-2臺階有關。
之前很多從回溯法到動態規劃都會發現dp[i]和回調函數的含義會有點變化。這次不會發生變化,直接拿過來。
dp[i]表示能夠到達第i個臺階需要的最小代價
dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]cost[i-2]])
最後返回dp[n]
public int minCostClimbingStairs(int[] cost) {
int n = cost.length;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 0;
for(int i=2;i<=n;i++){
dp[i] = Math.min(dp[i-2]+cost[i-2],dp[i-1]+cost[i-1]);
}
return dp[n];
}