函数题:跳台阶

一个楼梯共有 n级台阶,每次可以走一级或者两级,问从第 0 级台阶走到第 n 级台阶一共有多少种方案。

输入格式

共一行,包含一个整数 n。

输出格式

共一行,包含一个整数,表示方案数。

数据范围

1≤n≤15

输入样例:
5
输出样例:
8

#include <iostream>
//和深度优先搜索时差不多的原理。
using namespace std;

int n;//这里n设在两个函数之外,表示为一个全局变量,因为无论是哪个函数,都需要调用n这个数。
int ans;//用ans来表示走楼梯的方案数,到时候直接输出就行。
void f(int k)/*这个k,表示的是走的级数。观察这个函数你就可以初步的判断,这肯定和递归有关。
传的形参是k,里面的k在不断变化,变化了以后又调用这个函数,就是我们常说的调用自己。
   一般来说,我们调用函数,传的形参一般和main函数里面输入的有关,换句话说正常调用函数的时候,这里传的形参应该
   是n,而不是k,至于为什么要用递归,为什么要这样写,那就我后面慢慢讲述。*/

{
    if (k == n)//当逐步运行得到结果n时,就结束这一路径,然后往回走,直到又找到满足条件的,又继续运行。
        ans++;//走到得到n一次,就ans++。
    else if (k < n)
    {
        f(k + 1);/*这个表示函数的调用,是用k+1来替换k然后再次进入函数,不仅计算得到k+1的结果,也会继续
        运行里面的判断条件,如果满足这个条件,那ans++,然后就回溯继续运行这个函数里面的语句。
        说实话,这玩意是有点绕的,理解起来还是有难度。*/
        f(k + 2);
    }
}

int main()
{

    cin >> n;
    f(0);//这里是对k的初始化,表示k刚开始一个台阶也没走,就是0.
    cout << ans << endl;

    return 0;
}

 

   上面的过程图,就是当n=5时,怎样得到方案数为8的过程。可以发现,k==n时,就不会再接着递归运行了,表示着这一条路已经走完了,就不接着走了,直接ans++就行;从图中可以看出,一条路结束就是一个方案的成功,就直接计数,所以你可以看到,有几个5,那么就有几种方案,所以我才会画圆圈,就是方便计数。

   这个图我画的不标准,但是仍然可以看出,这是一个树形结构,这个的学名叫递归搜索树,就是后面算法要接触的深度优先搜索,简称DFS。这个是具体怎么运行的呢,是这样的,只要k<n,那么就k+1或者是k+2,因为题上说了每次走一级或者两级。注意,这个f(k+1)和f(k+2)是一起运行的,不管最后得到的k值是否能满足所给条件,它俩都是同时运行的。

   举个例子,当我们第一条路线一直走,走到4这里。因为4<5,所以要执行f(k+1)和f(k+2),这时候k就变成了5和6,但是根据条件,6不满足条件,不写,所以图中才只会有一个5,而没有6;至于f(k+2),k=6不满足条件,那就自动舍去6这个值。我们会发现,一个数下面是有两个k值的,因为走的是两种情况。  当k=3时,先调用函数,算的f(k+1)=4,其实就是把k替换成k+1,调用f(k+1)的时候,进入了函数,得到了结果4,然后又进行if 和else语句的条件判断,这个时候值为4,是等于n的,所以ans++,下面的else语句就不用运行了。到这里还没结束,找到一个方案后,之前是k=3,k+1=4,找到4以后,k值回溯到3,然后继续执行函数里面的语句,然后再进行判断运行。直到最终回溯到根结点0为止,结束。(这只是我现阶段的想法,因为掌握的知识不多,只能理解到这个地步,等到了后面学的东西多了,有了新的理解和感悟,再来补充和改正)。这一过程最好照着上面的过程图去理解,但脑袋里面想还是很有难度的。

递归是一大难点,但是是很重要的一个知识点,在后面的很多算法中均有使用,所以还是多多理解吧,争取掌握它。我写这些过程也很难受,用语言表示还是不好表述,但我还是写了,如有写的不好的地方,还请见谅,毕竟我也只是一个小白。

   

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值