鱼C论坛

 找回密码
 立即注册
查看: 1296|回复: 17

[已解决]爬楼梯

[复制链接]
发表于 2020-7-29 13:00:51 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 bangbang-ande 于 2020-7-29 17:47 编辑

题目是这样子的:

题目描述
楼梯有 N 阶,上楼可以一步上一阶,也可以一步上二阶。

编一个程序,计算共有多少种不同的走法。

输入格式
一个数字,楼梯数。

输出格式
输出走的方式总数。

输入输出样例
输入 #1
4
输出 #1
5
说明/提示
对于 60\%60% 的数据,N≤50;
对于 100\%100% 的数据,N≤5000。


然后写的代码是这样的:
  1. #include <stdio.h>

  2. int ans = 0;

  3. int f(int n){
  4.     if(n == 1){
  5.         ans += 1;
  6.         return 0;
  7.     }
  8.     if(n == 2){
  9.         ans += 2;
  10.         return 0;
  11.     }
  12.     f(n - 1);
  13.     f(n - 2);
  14. }

  15. int main(){
  16.     int n;
  17.     scanf("%d", &n);
  18.     f(n);
  19.     printf("%d", ans);
  20. }
复制代码

可是运行起来是四个通过,剩下的超了时间(时间复杂度1s, 空间复杂度125mb)
然后又改了一下:
  1. #include <stdio.h>

  2. int ans = 0;

  3. int f(int n){
  4.     if(n == 1 && n == 2){
  5.         ans += 1;
  6.         return 0;
  7.     }
  8.     f(n - 1);
  9.     f(n - 2);
  10. }

  11. int main(){
  12.     int n;
  13.     scanf("%d", &n);
  14.     f(n - 1);
  15.     printf("%d", ans);
  16. }
复制代码

结果空间复杂度又出问题。。。
请问还有没有更好的方法?

可以来下边那个网站测试
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
题目网站:https://www.luogu.com.cn/problem/P1255
最佳答案
2020-8-4 17:24:16
从我的力扣代码改的,这5000这种数据太大了,还得写个字符串表示大整数的加法,用动态规划从底层遍历到顶层结果就出来了
  1. #include<iostream>
  2. #include<vector>
  3. #include<string>

  4. using namespace std;

  5. vector<string> vec(5001, "0");

  6. string addStrings(string num1, string num2) //字符串加法:"1"+"1"="2"
  7. {
  8.         num1 = '0' + num1;
  9.         num2 = '0' + num2;
  10.         int len1 = num1.size();
  11.         int len2 = num2.size();

  12.         string ans = "";
  13.         int cry = 0;
  14.         len1--;
  15.         len2--;
  16.         char ch;
  17.         while (len1 != -1 && len2 != -1)
  18.         {
  19.                 ch = num1[len1] + num2[len2] + cry - '0';
  20.                 if (ch > '9')
  21.                 {
  22.                         ans = (char)(ch - 10) + ans;
  23.                         cry = 1;
  24.                 }
  25.                 else
  26.                 {
  27.                         ans = ch + ans;
  28.                         cry = 0;
  29.                 }
  30.                 len1--;
  31.                 len2--;
  32.         }

  33.         if (len1 == -1)
  34.                 while (len2 > -1)
  35.                 {
  36.                         ch = num2[len2] + cry;
  37.                         if (ch > '9')
  38.                         {
  39.                                 ans = (char)(ch - 10) + ans;
  40.                                 cry = 1;
  41.                         }
  42.                         else
  43.                         {
  44.                                 ans = ch + ans;
  45.                                 cry = 0;
  46.                         }
  47.                         len2--;
  48.                 }
  49.         else
  50.                 while (len1 > -1)
  51.                 {
  52.                         ch = num1[len1] + cry;
  53.                         if (ch > '9')
  54.                         {
  55.                                 ans = (char)(ch - 10) + ans;
  56.                                 cry = 1;
  57.                         }
  58.                         else
  59.                         {
  60.                                 ans = ch + ans;
  61.                                 cry = 0;
  62.                         }
  63.                         len1--;
  64.                 }

  65.         if (ans[0] == '0')
  66.                 ans = ans.substr(1);

  67.         return ans;
  68. }

  69. string  climbStairs(int n)
  70. {
  71.         vec[1] = "1";
  72.         vec[2] = "2";

  73.         if (n == 1)
  74.                 return "1";
  75.         if (n == 2)
  76.                 return "2";

  77.         for (int i = 3; i <= n; i++)
  78.                 vec[i] = addStrings(vec[i - 1], vec[i - 2]);

  79.         return vec[n];
  80. }

  81. int main()
  82. {
  83.     ios::sync_with_stdio(false);
  84.     int num;
  85.     cin >> num;
  86.     string ans = climbStairs(num);
  87.     cout << ans;

  88.     return 0;
  89. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-7-29 13:04:29 | 显示全部楼层
  1. public int climbStairs(int n) {
  2.     // base cases
  3.     if(n <= 0) return 0;
  4.     if(n == 1) return 1;
  5.     if(n == 2) return 2;
  6.    
  7.     int one_step_before = 2;
  8.     int two_steps_before = 1;
  9.     int all_ways = 0;
  10.    
  11.     for(int i=2; i<n; i++){
  12.         all_ways = one_step_before + two_steps_before;
  13.         two_steps_before = one_step_before;
  14.         one_step_before = all_ways;
  15.     }
  16.     return all_ways;
  17. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-29 13:46:53 | 显示全部楼层
你应该不是时间复杂度出问题,是最后忘了return了(结果报错了),还有你这个f函数不用返回值呀
  1. #include <stdio.h>

  2. int ans = 0;
  3. void f(int n){
  4.    
  5.     if(n == 1 && n == 2){
  6.         ans += 1;
  7.         return;
  8.     }
  9.     f(n - 1);
  10.     f(n - 2);
  11.     return;
  12. }

  13. int main(){
  14.     int n;
  15.     scanf("%d", &n);
  16.     f(n - 1);
  17.     printf("%d", ans);
  18. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-29 15:11:42 | 显示全部楼层
xiaosi4081 发表于 2020-7-29 13:46
你应该不是时间复杂度出问题,是最后忘了return了(结果报错了),还有你这个f函数不用返回值呀


但是还是不对啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-29 15:13:37 | 显示全部楼层

发错的内容(不要任何改动)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-29 15:37:10 | 显示全部楼层
递归函数执行次数太多了,改成递推就好了
另外,头像好评
  1. int climbStairs(int n){
  2.     int a=1, b=1;
  3.     for(int i = 1; i < n; i++)
  4.     {
  5.         b += a;
  6.         a = b - a;
  7.     }
  8.     return b;
  9. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-29 16:11:51 | 显示全部楼层
有大佬告诉我60\%60%是什么意思吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-29 17:41:02 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-29 20:23:34 | 显示全部楼层

请教:你这是 VC++ 程序吗?我用 VC++6.0 没通过。谢谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-29 20:31:33 | 显示全部楼层
风过无痕1989 发表于 2020-7-29 20:23
请教:你这是 VC++ 程序吗?我用 VC++6.0 没通过。谢谢!

是c程序
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-29 21:27:32 | 显示全部楼层

不是问你,你的程序当然是C程序啦
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-29 22:02:37 | 显示全部楼层
风过无痕1989 发表于 2020-7-29 20:23
请教:你这是 VC++ 程序吗?我用 VC++6.0 没通过。谢谢!

java
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-29 22:38:42 | 显示全部楼层
动态规划题目
leetcode测试通过
运行时间0 ms
内存消耗        5.2 MB

  1. int climbStairs(int n)
  2. {
  3.     int dp[n+3];
  4.     int i;
  5.    
  6.     dp[0]=0;
  7.     dp[1]=1;
  8.     dp[2]=2;
  9.    
  10.     for(i=3;i<=n;i++)
  11.     {
  12.         dp[i]=dp[i-1]+dp[i-2];
  13.     }
  14.     return dp[n];
  15. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-29 23:18:04 | 显示全部楼层
SHRS23 发表于 2020-7-29 22:38
动态规划题目
leetcode测试通过
运行时间0 ms

你可不可以试试这个测试网站:
https://www.luogu.com.cn/problem/P1255
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-30 13:39:17 | 显示全部楼层
本帖最后由 Cool_Breeze 于 2020-7-30 13:55 编辑
  1. #include <stdio.h>
  2. #define size_t long long

  3. int main()
  4. {
  5.         size_t n=0;
  6.         scanf("%d",&n);
  7.         register size_t f1=1;
  8.         register size_t f2=1;
  9.         if (n == 1 || n == 2 || n == 3)
  10.         {
  11.                 printf("%d", n);
  12.                 return 0;
  13.         }
  14.         else
  15.         {
  16.                 for(int i = 3;i < n;i++)
  17.                 {
  18.                         f1=f1+f2;
  19.                         f2=f2+f1;
  20.                 }
  21.         }
  22.         printf("%d", f1 + f2);
  23.         return 0;
  24. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-30 18:04:04 | 显示全部楼层
bangbang-ande 发表于 2020-7-29 23:18
你可不可以试试这个测试网站:
https://www.luogu.com.cn/problem/P1255

抱歉我没有洛谷账号
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-30 18:26:56 | 显示全部楼层
  1. #include<stdio.h>

  2. int climbStairs(int n)
  3. {
  4.     long long dp[n+3];
  5.     int i;
  6.    
  7.     dp[0]=0;
  8.     dp[1]=1;
  9.     dp[2]=2;
  10.    
  11.     for(i=3;i<=n;i++)
  12.     {
  13.         dp[i]=dp[i-1]+dp[i-2];
  14.     }
  15.     return dp[n];
  16. }

  17. int main()
  18. {
  19.     int n = 0;
  20.     scanf("%d",&n);
  21.     printf("%ld", climbStairs(n));
  22.     return 0;
  23. }
复制代码


注册试了一下发现我竟然三年前注册过。。。
这是WA50的程序,不想改了,洛谷这数据大的离谱,我看题解大家都高精加法做的。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-4 17:24:16 | 显示全部楼层    本楼为最佳答案   
从我的力扣代码改的,这5000这种数据太大了,还得写个字符串表示大整数的加法,用动态规划从底层遍历到顶层结果就出来了
  1. #include<iostream>
  2. #include<vector>
  3. #include<string>

  4. using namespace std;

  5. vector<string> vec(5001, "0");

  6. string addStrings(string num1, string num2) //字符串加法:"1"+"1"="2"
  7. {
  8.         num1 = '0' + num1;
  9.         num2 = '0' + num2;
  10.         int len1 = num1.size();
  11.         int len2 = num2.size();

  12.         string ans = "";
  13.         int cry = 0;
  14.         len1--;
  15.         len2--;
  16.         char ch;
  17.         while (len1 != -1 && len2 != -1)
  18.         {
  19.                 ch = num1[len1] + num2[len2] + cry - '0';
  20.                 if (ch > '9')
  21.                 {
  22.                         ans = (char)(ch - 10) + ans;
  23.                         cry = 1;
  24.                 }
  25.                 else
  26.                 {
  27.                         ans = ch + ans;
  28.                         cry = 0;
  29.                 }
  30.                 len1--;
  31.                 len2--;
  32.         }

  33.         if (len1 == -1)
  34.                 while (len2 > -1)
  35.                 {
  36.                         ch = num2[len2] + cry;
  37.                         if (ch > '9')
  38.                         {
  39.                                 ans = (char)(ch - 10) + ans;
  40.                                 cry = 1;
  41.                         }
  42.                         else
  43.                         {
  44.                                 ans = ch + ans;
  45.                                 cry = 0;
  46.                         }
  47.                         len2--;
  48.                 }
  49.         else
  50.                 while (len1 > -1)
  51.                 {
  52.                         ch = num1[len1] + cry;
  53.                         if (ch > '9')
  54.                         {
  55.                                 ans = (char)(ch - 10) + ans;
  56.                                 cry = 1;
  57.                         }
  58.                         else
  59.                         {
  60.                                 ans = ch + ans;
  61.                                 cry = 0;
  62.                         }
  63.                         len1--;
  64.                 }

  65.         if (ans[0] == '0')
  66.                 ans = ans.substr(1);

  67.         return ans;
  68. }

  69. string  climbStairs(int n)
  70. {
  71.         vec[1] = "1";
  72.         vec[2] = "2";

  73.         if (n == 1)
  74.                 return "1";
  75.         if (n == 2)
  76.                 return "2";

  77.         for (int i = 3; i <= n; i++)
  78.                 vec[i] = addStrings(vec[i - 1], vec[i - 2]);

  79.         return vec[n];
  80. }

  81. int main()
  82. {
  83.     ios::sync_with_stdio(false);
  84.     int num;
  85.     cin >> num;
  86.     string ans = climbStairs(num);
  87.     cout << ans;

  88.     return 0;
  89. }
复制代码
ans1.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-13 21:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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