HDU-2041超級樓梯
阿新 • • 發佈:2018-11-03
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),所以肯定會導致超時的。
執行結果如下: