假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
动态规划中的计数类问题:
1.确定状态
*最后一步:在到达第n阶之前,可能的位置在n-1或n-2阶阶梯上
*子问题:有多少种方法到达n-1或n-2阶阶梯
开数组:f(n)=到达n-1或n-2阶阶梯的方法数量
2.状态转移方程
到达第n阶阶梯的方法等于到达第n-1阶阶梯的方法加上到达第n-2阶阶梯的方法的数量之和
f(n)=f(n-1)+f(n-2);
3.初始条件和边界情况
初始条件:
(1)当n=1时,只有一种方法,f(1)=1;
(2)当n=2时,有两种方法,f(2)=2;
边界情况:最后一轮算n,n为n+1时停止
4.优化
代码:
int climbStairs(int n){
if(0==n) return 0;
if(1==n) return 1;
if(2==n) return 2;
const int size=n;
int dp[size];
dp[0]=1,dp[1]=2;
for(int i=2;i<n;++i){
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n-1];
}
斐波那契数列:
可以发现,f(n)=f(n-1)+f(n-2) (n>2);f(1)=1,f(2)=2;
所以计算f(n)即计算第n个斐波那契数
int climbStairs(int n){
if(0==n) return 0;
int first=1,sec=2;
int sum=0;
for(int i=3;i<=n;++i){
sum=first+sec;
first=sec;
sec=sum;
}
return sec;
}