1. 程式人生 > >HDU-2041超級樓梯

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),所以肯定會導致超時的。

執行結果如下:
在這裡插入圖片描述