1. 程式人生 > >leetcode-746-Min Cost Climbing Stairs(動態規劃)

leetcode-746-Min Cost Climbing Stairs(動態規劃)

PE each style XP 輸出 size ase ons 代碼簡化

題目描述:

On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed).

Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the floor, and you can either start from the step with index 0, or the step with index 1.

Example 1:

Input: cost = [10, 15, 20]
Output: 15
Explanation: Cheapest is start on cost[1], pay that cost and go to the top.

Example 2:

Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
Output: 6
Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3].

Note:

  1. cost will have a length in the range [2, 1000]
    .
  2. Every cost[i] will be an integer in the range [0, 999].

要完成的函數:

int minCostClimbingStairs(vector<int>& cost)

說明:

1、給定一個vector,裏面存放著從各個階梯“躍起”的代價,每次躍起可以躍起一個臺階,也可以一次性躍起兩個臺階。比如[1,100,1,1,1,100,1,1,100,1]第一個元素1,表示從第一個階梯躍起,到達第二個臺階,或者第三個臺階,的代價都是1。要求一直攀爬樓梯,直到到達vector之外,比如上面給的例子,一共10個臺階,那就要攀爬到第11級,到達vector之外,輸出所花費的最小代價。這道題限制攀爬樓梯可以從第一個臺階開始,也可以從第二個臺階開始。

2、上述題目是不是略微嗅到了一點動態規劃的味道,不需要找出全部可能的攀爬序列,只需要每次存儲一個狀態,然後攀爬到下一個臺階存儲另一個狀態。

不過這道題由於可以躍升一個臺階,也可以一次性躍升兩個臺階,所以我們需要存儲兩個值,比如一個是到達第三個臺階的最小花費,另一個是到達第四個臺階的最小花費,接著我們就可以計算到達第五個臺階和第六個臺階的最小花費,一直這樣計算下去。

代碼如下:

    
   int minCostClimbingStairs(vector<int>& cost) {
     //先計算從第一個臺階開始攀爬的情況
int i=1,j=2,s1=cost.size();//i和j表示當前到達的臺階,i在前,j在後 int costi=cost[0],costj=cost[0],total,totalnew;
     //costi表示攀爬到i這一位需要的最小花費,costj同理
while(j!=s1-1&&j!=s1-2) { costi=min(costi+cost[i],costj+cost[j]);//計算到達i+2位的最小花費 i+=2; costj=min(costi+cost[i],costj+cost[j]);//計算到達j+2位的最小花費 j+=2; } if(j==s1-2)//如果j之後還有一個元素 { costj=costj+cost[j]; costi=costi+cost[i]+cost[i+2]; total=min(costi,costj); } else {//如果j已經是最後一位 costi=costi+cost[i]; costj=costj+cost[j]; total=min(costi,costj); }
     //計算從第二個臺階開始攀爬的情況,下述代碼同理 i
=2,j=3; costi=cost[1],costj=cost[1]; while(j!=s1-1&&j!=s1-2) { costi=min(costi+cost[i],costj+cost[j]); i+=2; costj=min(costi+cost[i],costj+cost[j]); j+=2; } if(j==s1-2) { costj=costj+cost[j]; costi=costi+cost[i]+cost[i+2]; totalnew=min(costi,costj); } else { costi=costi+cost[i]; costj=costj+cost[j]; totalnew=min(costi,costj); } return min(total,totalnew); }

上述代碼實測14ms,beats 49.37% of cpp submissions。

3、改進:

可以從第一個臺階開始,也可以從第二個臺階開始,筆者隱隱覺得這種情況,和我們每一步要處理的兩個最小花費,有相似的地方。

於是,我們可以把從第二個臺階開始的情況,也納入處理的範疇,一起處理,這樣可以快很多,代碼如下:(附解釋,主要修改了costj的初始值)

    int minCostClimbingStairs(vector<int>& cost) 
    {
        int i=1,j=2,s1=cost.size();
        int costi=0,costj=min(costi+cost[i],cost[0]),total;
     //costi表示到達i也就是第二個臺階(i從0開始)的最小花費,當前為0
//costj表示到達j也就是第三個臺階(j從0開始)的最小花費,考慮從
     //第一個臺階開始攀爬和從第二個臺階開始攀爬的兩種情況
while(j!=s1-1&&j!=s1-2) { costi=min(costi+cost[i],costj+cost[j]); i+=2; costj=min(costi+cost[i],costj+cost[j]); j+=2; } if(j==s1-2)//把2中未改進的代碼簡化一下 total=min(costi+cost[i]+cost[i+2],costj+cost[j]); else total=min(costi+cost[i],costj+cost[j]); return total; }

上述代碼實測12ms,beats 93.11% of cpp submissions。

leetcode-746-Min Cost Climbing Stairs(動態規劃)