1. 程式人生 > >(HDOJ)1001——超級樓梯(遞推)

(HDOJ)1001——超級樓梯(遞推)

Problem Description

有一樓梯共M級,剛開始時你在第一級,若每次只能跨上一級或二級,要走上第M級,共有多少種走法?

Input

輸入資料首先包含一個整數N,表示測試例項的個數,然後是N行資料,每行包含一個整數M(1<=M<=40),表示樓梯的級數。

Output

對於每個測試例項,請輸出不同走法的數量

Sample Input

2
2
3

Sample Output

1
2

Author

lcy

Source

2005實驗班短學期考試


問題分析

其實這個題是一個動態規劃的題,但是用遞推也可以很快解決。

這個上臺階的題還是很經典的,假設前面所有的走法全部都得到了,求最後一個f(n)的走法就是f(n-1)+f(n-2),因為f(n)只有這兩種情況才能得到,所以就得到了遞推公式,所以可以開始程式設計了。

但是發現呼叫遞迴這個沒法通過,因為超時了,所以需要對其進行優化,其實遞迴或者遞推求解時候會又很多計算髮生重複,所以需要對這些重複的值進行儲存。另外設一個數組,將所有計算結果進行儲存,優先在數組裡面尋找看是否之前已經計算過,否則呼叫遞迴重新計算。

AC程式碼

#include<iostream>
#include<algorithm>
using namespace
std; int a[100];//設定一個儲存計算重複的資料 int f(int n){ int ans; if (n == 1) return 1; if (n == 2) return 1; if (n > 2)//如果N>2需要呼叫前面的n-1和n-2進行計算 { if (a[n] != -1){//優先檢視是否已經計算過 ans = a[n]; } else{//否則遞迴 ans = f(n - 1) + f(n - 2
); a[n] = ans;//記得將這個遞迴計算的結果寫入到以n為下標的陣列,其他遞推可以在計算時候直接呼叫這個值 } } return ans; } int main(){ int n,m; cin >> n; for (int i = 0; i < 100; i++) a[i] = -1;//將陣列置為-1 for (int i = 0; i < n; i++){ cin >> m; cout << f(m)<<endl; } return 0; }