返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言如何解决青蛙跳台阶问题
  • 726
分享到

C语言如何解决青蛙跳台阶问题

2023-06-29 00:06:47 726人浏览 薄情痞子
摘要

小编给大家分享一下C语言如何解决青蛙跳台阶问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1. 基础问题题目描述一只青蛙一次可以跳上 1 级台阶,也可以跳上 2

小编给大家分享一下C语言如何解决青蛙跳台阶问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

    1. 基础问题

    题目描述

    一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

    诺,就像下面这样

    C语言如何解决青蛙跳台阶问题

    解题思路

    其实我一看到这道题,我也是懵的,不知道从哪里着手分析,那我们就从最简单的情况开始分析。

    假如 n = 1,一共有一级台阶,显然就只有一种跳法

    一次跳1阶;

    C语言如何解决青蛙跳台阶问题

    假如 n = 2,一共有两级台阶,共有两种跳法

    跳1阶,再跳1阶

    C语言如何解决青蛙跳台阶问题

    跳2阶

    C语言如何解决青蛙跳台阶问题

    假设n = 3,共有三种跳法。

    跳1阶,跳1阶,再跳1阶

    C语言如何解决青蛙跳台阶问题

    跳1阶,再跳2阶

    C语言如何解决青蛙跳台阶问题

    跳2阶, 再跳1阶

    C语言如何解决青蛙跳台阶问题

    (注:此过程图是我从网上找的,实在是难得画啦)

    通过上面的分析,我们可以这样思考问题

    前往楼梯顶部的最后一步,要么跳1阶,要么跳2阶;

    C语言如何解决青蛙跳台阶问题

    先假设f(n)为 n 级台阶的总跳法数;

    那么第一次如果选择跳一级的话,剩下的 n-1 级台阶的跳法数就为f(n−1)。

    如果第一次跳两级的话,剩下的 n-2 级台阶的跳法就是f(n−2);

    现在青蛙一次只能跳一级或两级,所以我们可以推出以下公式:

    C语言如何解决青蛙跳台阶问题

    咦,这玩意儿不就是我们 斐波那契数 吗?

    只不过有一点不同的是,斐波那契数列一般是以1,1,2,3,5,8,13……开始的;

    而我们这是以1,2,3,5,8,13……开始的,少了最前面的一个1。

    代码实现

    上面说到这个过程有点类似于斐波那契数,但又不完全是,所以我们先看主代码部分

    #include <stdio.h>int jump(int n){    if (n < 3)    {        //假设n的范围是[0, 3]        return n;    }    else    {        //n>3的时候        return jump(n - 1) + jump(n - 2);    }}int main(){    int num = 0;    printf("请输入一个台阶数:> ");    scanf("%d", &num);    int ret = jump(num);        printf("小青蛙有 %d种 跳法\n", ret);    return 0;}

    运行结果

    C语言如何解决青蛙跳台阶问题

    但是,我们来看一下计算的过程

    要计算f(6),就需要先计算出子问题f(5)和f(4)

    然后要计算f(5),又要先算出子问题f(4)和f(3),以此类推。

    一直到f(2)和f(1),递归树才终止。

    因此,青蛙跳阶,递归解法的时间复杂度 等于O(1) * O(2ⁿ)=O(2ⁿ)

    C语言如何解决青蛙跳台阶问题

    你仔细观察这颗递归树,你会发现存在「大量重复计算」;

    比如f(4)被计算了两次,f(3)被重复计算了3次&hellip;所以这个递归算法低效的原因,就是存在大量的重复计算!

    所以我们可以对代码进行优化

    递归升级

    在递归法的基础上,新建一个长度为n的数组,用于在递归时存储f(0)至f(n) 的数字值,重复遇到某数字时则直接从数组取用,避免了重复的递归计算。

    所以我们设置一个数组,用于存放第一次计算某一个n的jump(n)。

    当每一次要计算一个jump(n)的时候,就先查看数组中以n为下标的地方是否有值,有的话就可以不调用jump(n),而直接从数组中取得结果值,否则再计算jump(n)。

    代码实现

    #include <stdio.h>long int f[1000]={0};int jump(int n){    //当只有一阶台阶的时候,只有一种上台阶的方式。        //当有2阶台阶的时候,有2种上台阶的方式,一种是一次上一阶,还有一种是一次上2个台阶。        //现在设有n阶台阶,如果n>2,那种应该有(先跳一阶)+(先跳2阶)的方式        //如果先跳一阶,那么就有jump(n-1)中方式。如果先跳2阶,那么就有jump(n-2)中方式。        //因此可以知道共有jump(n-1) + jump(n-2)种方式。    if(n==1)    {        f[1]=1;        return f[1];    }    if(n==0)    {        f[0]=1;        return f[0];    }    if(n==2)    {        f[2]=2;        return f[2];    }    else    {        if(f[n-1]!=0)        {            if(f[n-2]!=0)            {                return (f[n-1]+f[n-2]);            }            else            {                f[n-2]=jump(n-2);                return (f[n-1]+f[n-2]);            }        }        else        {            if(f[n-2]!=0)            {                f[n-1]=jump(n-1);                return (f[n-1]+f[n-2]);            }            else            {                f[n-1]=jump(n-1);                f[n-2]=jump(n-2);                return (f[n-1]+f[n-2]);            }        }    }}int main(){    int num = 0;    printf("请输入一个台阶数:> ");    scanf("%d", &num);    int ret = jump(num);    printf("小青蛙有 %d种 跳法\n", ret);    return 0;}

    运行结果

    C语言如何解决青蛙跳台阶问题

    动态规划解法

    很快我又发现,不必把所有的记录都记起来;

    假设我有3阶楼梯,我只需要知道跳2阶和跳1阶的方法数是多少就可以算出跳3阶的方法数;

    因此每次只需要保留n&minus;1阶和n&minus;2阶的方法数。

    代码实现

    #include <stdio.h>int jump(int n){    //n=0、1、2的时候,直接返回n即可    if (n < 3)    {        return n;    }        //第一个数为1    int one = 1;    //第二个数为2    int two = 2;    //用于存放前两个数之和    int sum = 0;     while (n > 2)    {        sum = one + two;        one = two;        two = sum;        n--;    }    return sum;}int main(){    int num = 0;    printf("请输入一个台阶数:> ");    scanf("%d", &num);    int ret = jump(num);    printf("小青蛙有 %d种 跳法\n", ret);    return 0;}

    运行结果

    C语言如何解决青蛙跳台阶问题

    2. 问题升级

    题目描述

    一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶&hellip;&hellip;,也可以跳n级,求该青蛙跳上一个n级的台阶总共需要多少种跳法。

    解题思路

    一只青蛙要想跳到n级台阶,可以从一级,二级&hellip;&hellip;,也就是说可以从任何一级跳到n级

    C语言如何解决青蛙跳台阶问题

    当台阶为1级时,f(1)=1;

    当台阶为2级时,f(2)=1+1=2;

    当台阶为3级时,f(3)=f(1)+f(2)+1=4;

    当台阶为4级时,f(4)=f(1)+f(2)+f(3)+1=8;

    当台阶为5级时,f(5)=f(1)+f(2)+f(3)+f(4)+1=16;

    所以递推公式我们很容易就能想到:f(n)=f(n&minus;1)+f(n&minus;2)+&hellip;&hellip;+f(2)+f(1)+f(0)

    最后这个f(0)是可以去掉的,因为0级就相当于没跳,所以f(0)=0

    然后我们把f(0)去掉再转换一下:f(n&minus;1)=f(n&minus;2)+f(n&minus;3)+&hellip;&hellip;+f(2)+f(1);

    推导过程

    我们列两个等式:

    ①f(n)=f(n&minus;1)+f(n&minus;2)+f(n&minus;3)+&hellip;+f(2)+f(1)

    ②f(n&minus;1)=f(n&minus;2)+f(n&minus;3)+&hellip;+f(2)+f(1)

    由①-②得,f(n)=2f(n&minus;1)

    代码实现

    递归方法

    代码示例

    int jump(int n){    if (n == 1)    {        return 1;    }    else    {        return 2 * jump(n - 1);    }}int main(){    int num = 0;    printf("请输入一个台阶数:> ");    scanf("%d", &num);    int ret = jump(num);    printf("小青蛙有 %d种 跳法\n", ret);    return 0;}

    运行结果

    C语言如何解决青蛙跳台阶问题

    非递归方法

    当然这里也可以用非递归的方式来实现

    那么非递归怎么去思考呢?

    可以这样理解:

    C语言如何解决青蛙跳台阶问题

    然后使用用函数pow(2,n -1),需要加头文件<math.h>

    但是我们这里可以不用库函数来实现,给大家介绍一种神奇的运算

    代码示例

    int jump(int n){    if (n == 1)    {        return 1;    }    else    {        return 1 << (n-1);    }}int main(){    int num = 0;    printf("请输入一个台阶数:> ");    scanf("%d", &num);    int ret = jump(num);    printf("小青蛙有 %d种 跳法\n", ret);    return 0;}

    运行结果

    C语言如何解决青蛙跳台阶问题

    我这里选择用<<左移操作符来计算

    以上是“C语言如何解决青蛙跳台阶问题”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网其他教程频道!

    --结束END--

    本文标题: C语言如何解决青蛙跳台阶问题

    本文链接: https://lsjlt.com/news/321486.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • C语言如何解决青蛙跳台阶问题
      小编给大家分享一下C语言如何解决青蛙跳台阶问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1. 基础问题题目描述一只青蛙一次可以跳上 1 级台阶,也可以跳上 2...
      99+
      2023-06-29
    • C语言 递归解决青蛙跳台阶问题
      目录前言一、求解思路二、代码实现1.参考代码2.运行结果总结 前言 一只青蛙一次可以跳1级或2级台阶,求当台阶数为n时青蛙有多少种跳法。 一、求解思路 台阶的数量为n。 当 n = ...
      99+
      2024-04-02
    • C语言解决青蛙跳台阶问题(升级版)
      目录1. 基础问题题目描述解题思路代码实现2. 问题升级题目描述解题思路代码实现3. 特性总结1. 基础问题 题目描述 一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙...
      99+
      2024-04-02
    • C语言中如何使用递归解决青蛙跳台阶问题
      这篇文章主要介绍C语言中如何使用递归解决青蛙跳台阶问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、求解思路台阶的数量为n。当 n = 1 时,青蛙有一种跳法,即跳1级台阶。当 n = 2 时,青蛙有两种跳法,即...
      99+
      2023-06-25
    • Java解决青蛙跳台阶问题流程
      1.问题描述 一只青蛙一次可以跳上1阶台阶,也可以跳上2阶台阶,求该青蛙跳上一个n阶台阶总共有多少种跳法? 2.画图分析  3.问题讲解  一只青蛙,要么1次跳2个台阶,要么1次跳...
      99+
      2024-04-02
    • C语言递归之汉诺塔和青蛙跳台阶问题
      递归就是一个函数执行过程中调用自己,在c语言中有很多关于递归的经典问题,例如:斐波那契数列问题、汉诺塔问题等,在研究递归问题时我们要注意三点: 1.递归的结束条件 2.递归在每次进行...
      99+
      2024-04-02
    • C 语言基础实现青蛙跳台阶和汉诺塔问题
      目录一、青蛙跳台阶题目思路分析1. 从跳法次数分析2. 从过程分析二、青蛙跳台阶变式1题目分析三、青蛙跳台阶变式2题目分析四、汉诺塔问题(求步数)题目思路分析五、汉诺塔问题(求移动过...
      99+
      2024-04-02
    • 如何从青蛙跳台阶开始来了解Dynamic Programming
      这篇文章给大家介绍如何从青蛙跳台阶开始来了解Dynamic Programming,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。动态规划(Dynamic Programming),简称...
      99+
      2024-04-02
    • C语言如何解决二叉堆问题
      这篇文章给大家分享的是有关C语言如何解决二叉堆问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、堆的概念1、概述堆是计算机科学中一类特殊的数据结构的统称。实现有很多,例如:大顶堆,小顶堆,斐波那契堆,左偏堆,...
      99+
      2023-06-26
    • C语言 如何用堆解决Topk问题
      目录前言TopK问题解题方法代码实现与讲解运行结果函数解读PrintTopK 解读TestTopK 解读前言 本篇将详细讲解如何利用小根堆的方法解决TopK问题,这么多数据要处理, ...
      99+
      2024-04-02
    • Python算法如何解决楼梯台阶问题
      这篇文章主要讲解了“Python算法如何解决楼梯台阶问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python算法如何解决楼梯台阶问题”吧!有一个有N个台阶的楼梯,你一次可以爬1或2个台...
      99+
      2023-06-02
    • 如何解决C语言中for循环问题
      本篇内容主要讲解“如何解决C语言中for循环问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决C语言中for循环问题”吧!今天分享一下C语言中的for循环中我们常常忽略的小问题。举一个小...
      99+
      2023-06-07
    • c语言内存溢出问题如何解决
      C语言内存溢出问题可以通过以下几种方式来解决:1. 检查代码逻辑:检查代码中的循环、递归、动态内存分配等地方是否存在错误,比如没有正...
      99+
      2023-10-10
      c语言
    • 如何使用C语言解决八皇后问题
      这篇文章主要讲解了“如何使用C语言解决八皇后问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用C语言解决八皇后问题”吧!前言八皇后问题是一个古老而著名的问题。该问题是19世纪著名的数...
      99+
      2023-06-08
    • C语言算法中如何解决佩奇借书问题
      小编给大家分享一下C语言算法中如何解决佩奇借书问题,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1. 问题描述佩奇有5本新书,要借给A、B、C这3位小朋友,若每人每次只能借1本,则可以有多少种不同的借法?2. 题目分析本题...
      99+
      2023-06-29
    • 如何解决owncloud php 语言失败问题
      本文操作环境:Windows7系统、PHP7.1、Dell G3。owncloud常见问题解决方案PHP 似乎没有设置好查询的系统环境变量。 用 getenv(\"PATH\") 测试只返回一个空值。解决方案:在 php...
      99+
      2014-11-08
      owncloud php
    • C语言怎么用堆解决Topk问题
      这篇文章给大家分享的是有关C语言怎么用堆解决Topk问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言将详细讲解如何利用小根堆的方法解决TopK问题,这么多数据要处理,该算法时间复度居然只需TopK问题Top...
      99+
      2023-06-21
    • c语言汉诺塔问题怎么解决
      解决汉诺塔问题的常见方法是使用递归。以下是使用递归解决C语言汉诺塔问题的示例代码:```c#include void hanoi(i...
      99+
      2023-10-07
      c语言
    • c语言怎么解决素数环问题
      素数环问题是指在一个圆环上排列一组互不相同的素数,使得任意两个相邻的素数之和也是素数。解决素数环问题的一种方法是使用回溯法。以下是一...
      99+
      2023-08-08
      c语言
    • C语言怎么解决Fibonacci数列问题
      在C语言中,可以使用循环或递归的方式来解决Fibonacci数列问题。 使用循环解决Fibonacci数列问题: #includ...
      99+
      2024-02-29
      C语言
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作