题目: 有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第m级,共有多少走法?
方法一:递归分治
递归分治就是把一个大的问题切分成k个小的子问题,子问题相较于原问题独立又有联系,然后递归地解决这些子问题,再把这些子问题合并得到原问题的答案。
思路:可以走一步,也可以走两步,从第n-1阶再走一步能到第n阶,从第n-2阶一次走两步能到第n阶。 所以,f(n)=f(n-1)+f(n-2)
//递归
//时间复杂度为T(n) = O(n2)
int countStages(int n)
{
if(n == 1)
return 0;
if(n == 2)
return 1;
if(n == 3)
return 2;
if(n > 3)
return countStages(n-1) + countStages(n-2);
return 0;
}
方法二:动态规划
一个问题的解依附于其子问题的解(动态规划的精髓所在)
F(1) = 1; F(2) = 2; F(n) = F(n-1)+F(n-2)(n>=3)
最优子结构: F(n-1)+F(n-2)是F(n)的最优子结构
边界: F(1) = 1; F(2) = 2;
状态转移公式:F(n) = F(n-1)+F(n-2)(n>=3)
//动态规划
//时间复杂度为T(n) = O(n)
//控件复杂度O(1)
int countDPStages(int n)
{
if(n == 1)
return 0;
if(n == 2)
return 1;
if(n == 3)
return 2;
int a=1;
int b=1;
int temp = 0;
for (int i = 3; i<=n; ++i)
{
temp = a+b;
a = b;
b = temp;
}
return temp;
}