C++ dp動態規劃經典問題-爬樓梯 [LeetCode 70]
阿新 • • 發佈:2021-09-16
(1)
假設你正在爬樓梯。需要 n階你才能到達樓頂。 每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢? 注意:給定 n 是一個正整數。 輸入: 3 輸出: 3 解釋: 有三種方法可以爬到樓頂。 1. 1 階 + 1 階 + 1 階 2. 1 階 + 2 階 3. 2 階 + 1 階 連結:https://leetcode-cn.com/problems/climbing-stairs
這裡參考@程式碼隨想錄的分析:
爬到第一層樓梯有一種方法,爬到二層樓梯有兩種方法。那麼第一層樓梯再跨兩步就到第三層 ,第二層樓梯再跨一步就到第三層。所以到第三層樓梯的狀態可以由第二層樓梯 和 到第一層樓梯狀態推匯出來,那麼就可以想到動態規劃了。
所以要定義一個一維陣列來記錄不同樓層的狀態,確定dp陣列以及下標的含義:dp[i]: 爬到第i層樓梯,有dp[i]種方法。
首先是dp[i - 1],上i-1層樓梯,有dp[i - 1]種方法,那麼再一步跳一個臺階不就是dp[i]了麼。
還有就是dp[i - 2],上i-2層樓梯,有dp[i - 2]種方法,那麼再一步跳兩個臺階不就是dp[i]了麼。
那麼dp[i]就是 dp[i - 1]與dp[i - 2]之和!所以dp[i] = dp[i - 1] + dp[i - 2] 。
由於dp[0]不確定意義,所以不做討論。
程式碼:
直接遞迴在n過大後,可能存在棧溢位的情況
int climbStairs(intn) { if(n==2) return 2; if(n==1) return 1; return climbStairs(n-1)+climbStairs(n-2); }
比較常用的一種解法是:
int climbStairs(int n) { if (n <= 1) return n; // 因為下面直接對dp[2]操作了,防止空指標 vector<int> dp(n + 1); dp[1] = 1; dp[2] = 2; for (int i = 3; i <= n; i++) { // 注意i是從3開始的 dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n];
節省空間的話,有:
int climbStairs(int n) { if(n<=2) return n; int i1=1,i2=2; int temp; for(int i=3;i<=n;i++) { temp=i1+i2; i1=i2; i2=temp; } return i2; }
(2)繼續深化,就是一步一個臺階,兩個臺階,三個臺階,直到 m個臺階,有多少種方法爬到n階樓頂
蕩塵滌汙,重整河山,便在今日