爬楼梯-完全背包版
將本題條件改為:一步一個臺階,兩個臺階,三個臺階,…,直到 m個臺階。問有多少種不同的方法可以爬到樓頂呢?
思路
1階,2階,… m階就是物品,樓頂就是背包。
每一階可以重復使用,例如跳了1階,還可以繼續跳1階。 問跳到樓頂有幾種方法其實就是問裝滿背包有幾種方法。
此時應該發現這就是一個完全背包問題了!
和題目動態規劃:377. 組合總和 Ⅳ基本就是一道題了。
確定dp數組以及下標的含義
dp[i]:爬到有i個臺階的樓頂,有dp[i]種方法。
確定遞推公式
在動態規劃:494.目標和 、 動態規劃:518.零錢兌換II、動態規劃:377. 組合總和 Ⅳ中,求裝滿背包有幾種方法,遞推公式一般都是dp[i] += dp[i - nums[j]];
而本題的dp[i]有幾種來源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]
那么遞推公式為:dp[i] += dp[i - j]
dp數組如何初始化
既然遞歸公式是 dp[i] += dp[i - j],那么dp[0] 一定為1,dp[0]是遞歸中一切數值的基礎所在,如果dp[0]是0的話,其他數值都是0了。
下標非0的dp[i]初始化為0,因為dp[i]是靠dp[i-j]累計上來的,dp[i]本身為0這樣才不會影響結果
確定遍歷順序
這是背包里求排列問題,即:1、2 步 和 2、1 步都是上三個臺階,但是這兩種方法不一樣!
所以需將target(背包)放在外循環,將nums(物品)放在內循環。
每一步可以走多次,這是完全背包,內循環需要從前向后遍歷。
class Solution { public:int climbStairs(int n) {vector<int> dp(n + 1, 0);dp[0] = 1;for (int i = 1; i <= n; i++) { // 遍歷背包for (int j = 1; j <= m; j++) { // 遍歷物品if (i - j >= 0) dp[i] += dp[i - j];}}return dp[n];} };總結