鱼C论坛

 找回密码
 立即注册
查看: 654|回复: 7

[已解决]求解递归问题

[复制链接]
发表于 2023-4-15 19:49:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
组长很喜欢爬楼梯,但是由于其腿不够长,每次最多只能一步跨越两个阶梯。比如他初始在楼底,跨越一个阶梯到达 1 号阶
梯,或者跨越两个阶梯到达 2号阶梯。由于他非常无聊,想把所有不同的到达楼顶的方式都尝试一遍。
但是他又很懒,不想自己计算,因此请你帮他算一算,对于一共有 n 个阶梯的楼梯,一共有多少总方法从楼底到达楼顶。
由于最后答案可能很大,输出最后的答案对 100007 取模的结果。
最佳答案
2023-4-15 19:53:28
isdkz 发表于 2023-4-15 19:51
这个问题可以用递归或者动态规划来求解。由于递归可能会产生很多重复计算,我们选择使用动态规划方法。这里 ...

这是C语言版本:

  1. #include <stdio.h>

  2. // 计算有多少种方法到达楼顶的函数
  3. int climb_stairs(int n) {
  4.     if (n <= 2) {
  5.         return n;
  6.     }

  7.     int dp[n + 1]; // 定义动态规划数组
  8.     dp[1] = 1;
  9.     dp[2] = 2;

  10.     // 从第3阶开始,计算到达每个阶梯的方法数
  11.     for (int i = 3; i <= n; i++) {
  12.         dp[i] = (dp[i - 1] + dp[i - 2]) % 100007; // 更新动态规划数组,取模100007防止整数溢出
  13.     }

  14.     return dp[n];
  15. }

  16. int main() {
  17.     int n;
  18.     printf("请输入楼梯的阶梯数: ");
  19.     scanf("%d", &n);

  20.     int result = climb_stairs(n);
  21.     printf("一共有 %d 种方法到达楼顶。\n", result);

  22.     return 0;
  23. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-15 19:51:37 | 显示全部楼层
本帖最后由 sfqxx 于 2023-4-15 19:53 编辑

可以使用动态规划来解决这个问题。对于第 i 个楼梯(从第 0 个开始计数),设 s 表示从楼底到达该楼梯的所有方法的数量。则有 s[0]=1,s[1]=1,s[2]=2,对于 i>2,有以下转移方程:

s = (s[i-1] + s[i-2]) % 100007

最终答案为 s[n],其中 n 为楼梯总数。下面是具体的 Python 代码实现:
  1. MOD = 100007

  2. def climb_stairs(n):
  3.     if n == 0 or n == 1:
  4.         return 1
  5.     if n == 2:
  6.         return 2

  7.     s = [0] * (n+1)
  8.     s[0] = 1
  9.     s[1] = 1
  10.     s[2] = 2

  11.     for i in range(3, n+1):
  12.         s[i] = (s[i-1] + s[i-2]) % MOD

  13.     return s[n]

  14. # 测试样例
  15. print(climb_stairs(3)) # 输出为 3
复制代码

在上面的代码中,MOD 是取模的数。当 n=0 或 n=1 时,只有一种到达楼顶的方法,因此直接返回 1;当 n=2 时,有两种到达楼顶的方法,直接返回 2。对于 i>2,使用循环计算 s 数组并利用取模运算避免答案过大的问题。最后返回 s[n] 即可。
有用请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-15 19:51:38 | 显示全部楼层
这个问题可以用递归或者动态规划来求解。由于递归可能会产生很多重复计算,我们选择使用动态规划方法。这里是一个Python程序,可以求解这个问题:

  1. def climb_stairs(n):
  2.     if n <= 2:
  3.         return n

  4.     dp = [0] * (n + 1)
  5.     dp[1] = 1
  6.     dp[2] = 2

  7.     for i in range(3, n + 1):
  8.         dp[i] = (dp[i - 1] + dp[i - 2]) % 100007

  9.     return dp[n]

  10. n = int(input("请输入楼梯的阶梯数: "))
  11. result = climb_stairs(n)
  12. print("一共有 %d 种方法到达楼顶。" % result)
复制代码


使用这个程序,你可以计算出对于给定楼梯数 n 的情况下,有多少种不同的方式到达楼顶。最后的答案会对 100007 取模。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-15 19:53:28 | 显示全部楼层    本楼为最佳答案   
isdkz 发表于 2023-4-15 19:51
这个问题可以用递归或者动态规划来求解。由于递归可能会产生很多重复计算,我们选择使用动态规划方法。这里 ...

这是C语言版本:

  1. #include <stdio.h>

  2. // 计算有多少种方法到达楼顶的函数
  3. int climb_stairs(int n) {
  4.     if (n <= 2) {
  5.         return n;
  6.     }

  7.     int dp[n + 1]; // 定义动态规划数组
  8.     dp[1] = 1;
  9.     dp[2] = 2;

  10.     // 从第3阶开始,计算到达每个阶梯的方法数
  11.     for (int i = 3; i <= n; i++) {
  12.         dp[i] = (dp[i - 1] + dp[i - 2]) % 100007; // 更新动态规划数组,取模100007防止整数溢出
  13.     }

  14.     return dp[n];
  15. }

  16. int main() {
  17.     int n;
  18.     printf("请输入楼梯的阶梯数: ");
  19.     scanf("%d", &n);

  20.     int result = climb_stairs(n);
  21.     printf("一共有 %d 种方法到达楼顶。\n", result);

  22.     return 0;
  23. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-15 19:56:54 | 显示全部楼层
isdkz 发表于 2023-4-15 19:53
这是C语言版本:

这是递归版本:

  1. #include <stdio.h>

  2. // 计算递归方法的函数
  3. int climb_stairs_recursive(int n) {
  4.     if (n == 1) {
  5.         return 1;
  6.     }
  7.     if (n == 2) {
  8.         return 2;
  9.     }

  10.     // 递归调用
  11.     return (climb_stairs_recursive(n - 1) + climb_stairs_recursive(n - 2)) % 100007;
  12. }

  13. int main() {
  14.     int n;
  15.     printf("请输入楼梯的阶梯数: ");
  16.     scanf("%d", &n);

  17.     int result = climb_stairs_recursive(n);
  18.     printf("一共有 %d 种方法到达楼顶。\n", result);

  19.     return 0;
  20. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-15 20:03:35 | 显示全部楼层
isdkz 发表于 2023-4-15 19:51
这个问题可以用递归或者动态规划来求解。由于递归可能会产生很多重复计算,我们选择使用动态规划方法。这里 ...

我希望得到用c或c++写的代码,动态管理不懂,递归最好
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-15 20:06:47 | 显示全部楼层
白痴爱面包 发表于 2023-4-15 20:03
我希望得到用c或c++写的代码,动态管理不懂,递归最好

我在最后面发了一个递归版本
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-15 20:26:28 | 显示全部楼层
  1. #include <bits/stdc++.h>
  2. using namespace std;

  3. const int mod = 100007;

  4. int climb(int stair){
  5.     if(stair <= 1) return 1;
  6.     // 递归边界, 小于 1 就只有一种方法了
  7.     return (climb(stair - 1) + climb(stair - 2)) % mod;
  8.     // 走到这个台阶的方法数是 stair-1 阶方法数 + stair-2 阶方法数
  9. }
  10. int n;

  11. int main(){
  12.     ios::sync_with_stdio(0);
  13.     cin.tie(0);

  14.     cin >> n;
  15.     cout << climb(n);
  16.    
  17.     return 0;
  18. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-1 23:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表