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