【動態規劃】爬樓梯問題
阿新 • • 發佈:2019-02-15
1.問題描述
一個人爬樓梯,每次只能爬1個或兩個臺階,假設有n個臺階,那麼這個人有多少種不同的爬樓梯方法
2.分析
如果n==1,顯然只有從0->1一種方法f(1)=1;
如果n==2,那麼有0->1->2、0->2兩種方法f(2)=2;
如果n==3,那麼可以先爬到第1階,然後爬兩個臺階,或者先爬到第二階,然後爬一個臺階,顯然f(3)=f(2)+f(1);
……
推廣到一般情況,對於n(n>=3)個臺階,可以先爬到第n-1個臺階,然後再爬一個臺階,或者先爬到n-2個臺階,然後爬2個臺階,因此有f(n)=f(n-1)+f(n-2)。
那麼動態規劃的遞推公式和邊界條件都有了,即:
3.程式程式碼
根據遞推公式,可以寫如下程式碼輕鬆解決問題:
#include<stdio.h>
long long fun(int n);
int main()
{
printf("%lld ",fun(80));
return 0;
}
long long fun(int n)
{
if(n==1)
return 1;
else if(n==2)
return 2;
else if(n>2)
return fun(n-1)+fun(n-2);
}
注意:fun(80)的結果非常大,程式執行時間很長,測試的時候可以用小一點的數字測試。
雖然程式碼簡單,但是顯然這種方法實在是太耗時間了,遞迴函式多次重複計算中間結果。我們改進以下,開一個數組來儲存中間結果。
#include<stdio.h>
long long calc(long long step[],int n);
long long step[101]={0};
int main()
{
int n;
scanf("%d",&n);
int i=1;
for(i=1;i<=n;i++)
printf("%lld ",calc(step,i));
return 0;
}
long long calc(long long step[],int n)
{
long long i;
if(n<=0 )
return 0;
step[0]=1;
step[1]=1;
if(n>=2&&step[n-1]>0&&step[n-2]>0)
{
step[n] = step[n-1] + step[n-2];
return step[n];
}
else if(n>=2)
{
for(i=2;i<=n;i++)
step[i] = step[i-1]+step[i-2];
}
return step[n];
}