分析:
动态规划五部曲:
1、dp数组以及下标的含义
在这里dp数组定义为从第1个阶梯爬到第i个阶梯的不同方法数
2、递推公式
由题可知每一次可走一个阶梯或者两个阶梯,即当前阶梯可由前一个阶梯走一步或者前两个阶梯走两步得到,即:
dp[i] = dp[i-1]+dp[i-2];
3、如何初始化
分析得:
dp[1] = 1;dp[2] = 2;
4、确定遍历顺序:从前往后
5、举例推导(前10个dp[i])
1 2 3 5 8 13 21 34 55
题解:
class Solution {
public:
int climbStairs(int n) {
//分析可得 该问题递推式与斐波那契数列递推式并无差别
//先考虑特殊情况 n=1或2
if(n<=2){
return n;
}
//dp数组 下标从1 开始
vector<int> dp(n+1);
//初始化
dp[1]=1;
dp[2] = 2;
//遍历
for(int i = 3;i<=n;i++){
dp[i] = dp[i-1]+dp[i-2];
}
return dp[n];
}
};
稍加改动,变为完全背包,在原题的基础上,改为:每次可以爬1、2或者m 个台阶。问有多少种不同的方法可以爬到楼顶呢?
动态规划五部曲:
1、确定dp数组及其下标含义
dp[j]:爬到有j个台阶的楼顶,有dp[j]种方法
2、确定递推式
dp[j] += dp[j-i] i意为每次可爬的楼梯层数
3、如何初始化
dp[0] = 1;
4、确定遍历顺序
物品在内层循环 计算排列数 从前往后遍历
5、举例推导dp数组 m=2 n=2
dp数组变化:
1 1 0
1 1 2
题解:将下述m改为2即为本题完全背包题解
class Solution {
public:
int climbStairs(int n) {
//采用完全背包问题做
//dp[j]:爬到有j个台阶的楼顶,有dp[j]种方法
//dp[j] += dp[j-i] i意为每次可爬的楼梯层数
//定义dp数组
vector<int> dp(n+1);
//初始化dp
dp[0] = 1;
//计算dp 物品在内层循环 计算排列数
for(int j = 1;j<=n;j++){
for(int i = 1;i<=m;i++){
if(j-i>=0){
dp[j]+=dp[j-i];
}
}
}
return dp[n];
}
};