彻底解决爬楼梯问题

话不多说,我们直接进入正题

首先,举个最经典的爬楼梯问题:

  1. - ####假设你正在爬楼梯,有n级楼梯,每次你只能爬1步或者3步,请问有多少种不同的方法爬到楼顶部?

解决这个问题我们可以用到很多方法来求解,如递归调用,备忘录法,动态规划,以及斐波那契数列的通项公式。方法虽多,但只要抓住爬楼梯问题的本质—斐波那契数列。一切就很好办了。

接下来对题目进行分析

  1. - 只有1个台阶的时候 总共有1种走法
  2. - 只有2个台阶的时候 总共有1种走法
  3. - 只有3个台阶的时候 总共有2种走法
  4. - 只有4个台阶的时候 总共有3种走法
  5. - 只有5个台阶的时候 总共有4种走法
  6. - ......

此时我们发现规律:f(n)=f(n-1)+f(n-3),这个递推公式正符合斐波那契数列
还有一个问题:要是遇到了其他的走楼梯方式又该怎么办呢?一样的我们同样如此分析得到其他的表达式:

  1. - 每次可以上1级,2级.
  2. -:f(n)=f(n-1)+f(n-2)
  3. - 每次可以上1级,2级,3级.
  4. -:f(n)=f(n-1)+f(n-2)+f(n-3)
  5. ......

有了这个递推公式就好办事了,在这里我只贴出递归法和优化动态规划


递归调用法

  1. #include<iostream>
  2. using namespace std;
  3. long mod=1000000000+7;
  4. //答案很大时用mod=(1e9+7)输出
  5. //递归函数实现:f(n)=f(n-1)+f(n-3)
  6. long Num(int n){
  7. //n<4独立赋值
  8. if(n==1) return 1;
  9. if(n==2) return 1;
  10. if(n==3) return 2;
  11. else return Num(n-1)%mod+Num(n-3)%mod;
  12. }
  13. int main(){
  14. int n;
  15. cin>>n;
  16. cout<<Num(n)<<endl;
  17. //while(cin>>n)cout<<Num(n)<<endl;
  18. return 0;
  19. }

动态规划

  1. #include<iostream>
  2. using namespace std;
  3. long mod=1000000000+7;
  4. //答案很大时用mod=(1e9+7)输出
  5. //函数实现:f(n)=f(n-1)+f(n-3)
  6. long Num(int n){
  7. long add[n+1];
  8. //n<4单独赋值
  9. add[1]=1;
  10. add[2]=1;
  11. add[3]=2;
  12. if(n==1) return 1;
  13. if(n==2) return 1;
  14. //方法实现
  15. for(int i=4;i<=n;i++){
  16. add[i]=add[i-1]%mod+add[i-3]%mod;
  17. }
  18. return add[n]%mod;
  19. }
  20. int main(){
  21. int n;
  22. cin>>n;
  23. cout<<Num(n)<<endl;
  24. //while(cin>>n)cout<<Num(n)<<endl;
  25. return 0;
  26. }

使用递归调用往往在解决n比较小的时候速度较快,一旦n超过某个范围的数,速度就会很慢。因此n较大时建议使用动态规划

点赞(0)
 

6.6 分

3 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论