HDU-2041超级楼梯

HDU-2041超级楼梯

题目:
有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?
Input
输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M(1<=M<=40),表示楼梯的级数。
Output
对于每个测试实例,请输出不同走法的数量
Sample Input
2
2
3
Sample Output
1
2

先给出正确代码:


#include<iostream>
#include<cstdio>
using namespace std;
int a[50];
//打表
void setfn()
{
    int i;
    a[1] = 0;
    a[2] = 1;
    a[3] = 2;
    for(i = 4;i <= 40;i++)
    {
        a[i] = a[i - 1] + a[i - 2];
    }
}
int main()
{
    int n,m;
    setfn();
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&m);
        cout << a[m] << endl;
    }
    return 0;
}

解题思路:
因为第一阶梯为1,简述f(1) = 0;
f(2) = 1;从第一阶梯到第二级阶梯只能走一步,只有一种走法
f(3) = 2;从第一阶梯到第三级阶梯有两步分为跨一步或或两步。
f(4) = 3;

假如要到达第n层,那么到达第n层的总共走法分为两部分,第一部分为走一步到达第n层的总共数量,第二部分为走两步到达第n层的总共数量,得出公式:f[i] = f[i - 1] + f[i - 2]; 可以看出这是一个费布拉切数列,所以想到使用动态规划,把4到40的所有结果打表打出来(复杂度为o(n)),等后来要用的时候直接调用就可以了。如果不打表就会超时。

其实刚开始的时候本人没使用这种方法,错误代码如下:

#include<iostream>
#include<cstdio>
using namespace std;

void search_step(int m,int n,int &count)
{
    if(n == m) count++;
    else if(m < n)
    {
    	search_step(m + 1,n,count);
    	search_step(m + 2,n,count);
    }
    return;
}

int main()
{
    int n,m,count;
    int a[40];
    for(int i = 2;i <= 40;i++)
    {
        count = 0;
        search_step(1,i,count);
        a[i] = count;
    }
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&m);
        cout << a[m] << endl;
    }
    return 0;
}

同样也是打表,但是这个递归的层数大大增加,导致复杂度远超o(n),所以肯定会导致超时的。

运行结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41998938/article/details/83352502