青蛙跳台阶:我如何得知它是一道斐波那契数列题?——应用题破题“三板斧”(一)

简介: 这篇内容介绍了C语言学习中的经典例题——斐波那契数列,强调了解题思路的重要性。斐波那契数列是一个数列,其中每个数是前两个数的和。文章指出,很多类似题目,如“青蛙跳台阶”,实质上都在考察斐波那契数列的实现。文中提供了斐波那契数列的定义、代码实现和递归与非递归的思路,并鼓励读者从问题中分析出解题模型,而非直接套用已知方法。此外,还提及了一道相关题目“矩形覆盖问题”,以供进一步练习。

前言


C语言初学者在学习“递归与循环”章节时,一定会遇到“不死兔子”这道经典例题。



简而言之,它就是一个数列,除了第一项与第二项值为1以外,所有的项的值都等于其前两项的值之和:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)


在编程学习中,当单考斐波那契数列,即题目直接要求编写斐波那契数列代码时,许多同学并不会被难到。然而,当题干转变提问思路,转而提问“青蛙跳台阶有几种跳法”“小矩形摆大矩形有几种摆法”时,许多人就懵了:没有意识到其实这样的题干本质上还是在考察斐波那契数列的实现。


是的,斐波那契数列考题(或者说有很多的应用题),难点或许并不在代码实现,而在如何从看似有些“莫名其妙”的题干中分析出,这是一道考xxx的例题。


一些同学疑惑,自己怎么能想到用斐波那契数列求解呢?事实上,我们只需要会分析出恰当的办法解出来就好了,而不必纠结于“我看不出这用斐波那契写啊,那我就不会做了”。分析的过程是最重要的,无非是我们经过一番分析发现,恰好我们的解题思路和斐波那契一样,而不是早就知道了用这个方法,然后往题目里套。


因而,本文以应用题“青蛙跳台阶”为引例,讲解如何破题并分析出题干背后的考点;并在文末贴上另一道相对而言少见的相关题目:矩形覆盖问题。


这两道题都将附上详解,希望各位读者能有所收获。


一、斐波那契阿数列基础知识


本文默认大家都熟悉斐波那契数列的基础知识:包括最基础的代码编写思路和具体实现。不过还是考虑到也许一些同学一下子反应不过来把基础知识给忘了,因而在正文开始前,先贴上斐波那契数列的代码实现。不需要的同学可以直接跳过。


1. 斐波那契数列定义:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)


2. 求斐波那契数列的第N项


//求Fib数列第n项
 
//非递归
int main(){
    int f1 = 1;
    int f2 = 1;
    int fn,n;
 
    scanf("%d",&n);
    
    for(int i = 3; i <= n; i++){
        fn = f1 + f2;
        f1 = f2;
        f2 = fn;
    }
 
    printf("%d",fn);
 
    return 0;
}
 
//递归
int Fib(int n){
    if(n <= 0){
        return 0;
    }
    
    if(n == 1){
        return 1;
    }
 
    return Fib(n - 1) + Fib(n - 2)
}
 


3. 实现思路


从Fib的数学定义可以非常简单地得出递归思路:除了第1项和第2项值为1(第0项或负数项,这里默认为0),所有的项的值都是前两项之和F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)



非递归的思路类似于“滚车轮”,示意图如下:



如图:通过f1 = f2;f2 = fn实现迭代


f1和f2像两只“脚”,通过将三个数中的后一个赋值给前一个,实现整体向右不断叠加计算。


基础铺垫的部分简单地说明到这里,如果还有朋友们有不理解的地方,可以移步别的博主的优秀解析。本文在此不再赘述。


二、引例:青蛙跳台阶


牛客网习题链接


https://www.nowcoder.com/practice/ebf04de0e02c486099d78b7c3aaec255?tpId=107&&tqId=33398&rp=1&ru=/ta/beginner-programmers&qru=/ta/beginner-programmers/question-ranking


题干如下



题感较好或是曾经刷到过该题的同学应当一眼就能看出,该题就是斐波那契数列的经典习题。事实上题目暗示的也很明确:“一次可以走1级或2级台阶”“一共有多少种走法”。在谈到“一共有多少种办法”的时候,也许想到不断叠加是一件很自然的事情;或者干脆直接死记硬背地记住。从单题的角度看,固然是可行的,但对大多数第一次接触的同学而言,这样的解释和“马后炮”一样,并不靠谱。


采取上述方法的同学可以先尝试直接跳到最后的拓展例题(如果没接触那个例题的话),或者思考如果自己并不提前知道这两道应用题的解法而是从头分析,能不能分析出来。如果不能,那么以上的方式或许就有些欠妥(当然,应付学校的考试是没问题的)。


在分析问题时,我们一般采用这样的方法:题目表意 ----> 模型 ----> 代码,即从题干字面意思中转换成解题的模型(姑且这么叫吧),然后再根据模型逐步求精,编写代码。下面就第一步 表意--模型,展开详细的介绍。



青蛙跳台阶:我如何得知它是一道斐波那契数列题?——应用题破题“三板斧”(二)+  https://developer.aliyun.com/article/1518376?spm=a2c6h.13148508.setting.14.16ee4f0ePJ4B4k


相关文章
|
1月前
|
机器学习/深度学习 算法 测试技术
青蛙跳台阶:我如何得知它是一道斐波那契数列题?——应用题破题“三板斧”(二)
这篇内容是关于解题策略的,主要介绍了在面对应用题时可以采用的“三板斧”方法:举例、模拟和找规律。通过一个走楼梯的例子详细解释了这三个步骤如何运用。首先,举例将抽象问题具体化,比如走5级台阶有几种方式。其次,通过模拟不同情况,例如思考走每一步的可能,发现递归或循环的模式。最后,通过找规律归纳出一般性的解决方案,这里发现走台阶问题与斐波那契数列相关。文章还提到了一个拓展案例——矩形覆盖问题,同样可以用类似的方法分析。总的来说,文章强调了解题过程中理解和转化问题的重要性,以及通过训练提升这方面能力。
23 0
|
1月前
|
测试技术
【一刷《剑指Offer》】面试题 9:斐波那契数列(扩展:青蛙跳台阶、矩阵覆盖)
【一刷《剑指Offer》】面试题 9:斐波那契数列(扩展:青蛙跳台阶、矩阵覆盖)
|
1月前
【错题集-编程题】过河卒(动态规划-路径问题)
【错题集-编程题】过河卒(动态规划-路径问题)
|
1月前
|
C语言
每天一道C语言编程(递归:斐波那契数,母牛的故事)
每天一道C语言编程(递归:斐波那契数,母牛的故事)
12 0
|
1月前
日拱一卒,月进一步(6)(杨辉三角2)
119. 杨辉三角 II - 力扣(LeetCode)
18 0
|
1月前
|
Java C语言 C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-基础练习 Fibonacci数列
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-基础练习 Fibonacci数列
26 0
|
1月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-基础练习 杨辉三角形(最好的基础题,没有之一)
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-基础练习 杨辉三角形(最好的基础题,没有之一)
23 0
|
1月前
|
Java C语言 C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-基础练习 字母图形
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-基础练习 字母图形
28 0
|
9月前
|
机器学习/深度学习
P1403 [AHOI2005]约数研究(数学归纳,细心分析)
P1403 [AHOI2005]约数研究(数学归纳,细心分析)
39 0
|
10月前
|
存储 算法 C语言
深度理解递归,手撕经典递归问题(汉诺塔,青蛙跳台阶),保姆级教学。
深度理解递归,手撕经典递归问题(汉诺塔,青蛙跳台阶),保姆级教学。