【青蛙跳台阶问题 您所在的位置:网站首页 兔子总共有多少种多少属 【青蛙跳台阶问题

【青蛙跳台阶问题

2024-07-16 12:16| 来源: 网络整理| 查看: 265

青蛙跳台阶问题 —— (三种算法) 一.题目介绍1.1.题目1.2.图示 二.解题思路三.题解及其相关算法3.1.递归分治法3.2.动态规划算法(Dynamic Programming)3.3.斐波那契数列法 四.注意细节

一.题目介绍 1.1.题目

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1: 输入:n = 2 输出:2

示例 2: 输入:n = 7 输出:21

示例 3: 输入:n = 0 输出:1

提示: 0 return 1; } else if (n == 2) { return 2; } else { return climbStairs(n - 1)%con + climbStairs(n - 2)%con; } } int main() { int n; printf("请输入楼梯的阶数:"); scanf("%d", &n); int ways = climbStairs(n); printf("%d 阶楼梯一共有 %d 种跳法。\n", n, ways); return 0; }

在这里插入图片描述

3.2.动态规划算法(Dynamic Programming)

动态规划算法(Dynamic Programming)(记忆化递归法): 动态规划: 是一种用于解决多阶段决策问题的算法,它通过将问题分解为更小的子问题,并通过存储已经解决的子问题的结果来避免重复计算。 原理: 在递归法的基础上,新建一个长度为 n的数组,用于在递归时存储 f(0)至 f(n)的数字值,重复遇到某数字时则直接从数组取用,避免了重复的递归计算。 缺点: 记忆化存储的数组需要使用 O(N)的额外空间。

#define MAX 100 int ClimbStairs(int number) { int con = (int)1e9 + 7; if (number == 1) return 1; else if (number == 2) return 2; else { int dp[MAX]; dp[1] = 1; dp[2] = 2; int i = 0; for (i = 3; i int n; printf("请输入楼梯的阶数:"); scanf("%d", &n); int ways = climbStairs(n); printf("%d 阶楼梯一共有 %d 种跳法。\n", n, ways); return 0; }

在这里插入图片描述

3.3.斐波那契数列法

斐波那契数列法: 原理: 以斐波那契数列性质 f(n + 1) = f(n) + f(n - 1)为转移方程。 从计算效率、空间复杂度上看,斐波那契数列法是本题的最佳解法。

int fbnq(int n) { int con = (int)1e9 + 7; int first = 0; int second = 1; int tem = 0; while (n--) { tem = first + second; first = second % con; second = tem % con; } return first; } int ClimbStairs(int n) { return fbnq(n + 1); } int main() { int n; printf("请输入楼梯的阶数:"); scanf("%d", &n); int ways = ClimbStairs(n); printf("%d 阶楼梯一共有 %d 种跳法。\n", n, ways); return 0; }

在这里插入图片描述

四.注意细节

为什么要模1000000007。 参考:https://link.zhihu.com/?target=https%3A//www.liuchuo.net/archives/645 大数相乘,大数的排列组合等为什么要取模 一、1000000007是一个质数(素数),对质数取余能最大程度避免结果冲突/重复 二、int32位的最大值为2147483647,所以对于int32位来说1000000007足够大。int64位的最大值为2^63-1,用最大值模1000000007的结果求平方,不会在int64中溢出。 所以在大数相乘问题中,因为(a∗b)%c=((a%c)∗(b%c))%c,所以相乘时两边都对1000000007取模,再保存在int64里面不会溢出。 这道题为什么要取模,取模前后的值不就变了吗? 确实:取模前 f(43) = 701408733, f(44) = 1134903170, f(45) = 1836311903, 但是 f(46) > 2147483647结果就溢出了。 取模后 f(43) = 701408733, f(44) = 134903163 , f(45) = 836311896, f(46) = 971215059没有溢出。取模之后能够计算更多的情况,如 f(46)。这道题的测试答案与取模后的结果一致。

总结一下,这道题要模1000000007的根本原因是标准答案取模了1000000007。不过大数情况下为了防止溢出,模1000000007是通用做法,原因见第一点。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有