遞迴系列---1.青蛙跳臺階 (10分)
阿新 • • 發佈:2021-01-27
遞迴系列—1.青蛙跳臺階 (10分)
在PTA上刷題,遇到這個問題,高三的時候聽數學老師講過,當時不知道什麼是遞迴,現在明白了,覺得有點意思。
題意:
一隻青蛙一次可以跳上 1 級臺階,也可以跳上2 級。求該青蛙跳上一個n 級的臺階總共有多少種跳法。
輸入格式:
首先輸入數字n,代表接下來有n組輸入,50>=n>=0,然後每行一個數字,代表臺階數,數字為小於60的整數
輸出格式:
對每一組輸入,輸出青蛙的跳法。
輸入樣例:
3
1
2
3
輸出樣例:
1
2
3
我對於遞迴的理解是,大的問題,可以轉換成相同的,但是規模減少的相同的子問題,並且子問題減少的最小還要有解(遞迴有基準情況)。
回到這個問題,這個問題想考的是遞迴,但是我遞迴最後一個測試點超時了,後來看了看資料,階梯數小於等於60,單個測試了n=50時就不能輸出結果,爆棧了。看了網上,應該是可以優化的,在遞迴之前,判斷一下,這個數有沒有算過,算過就直接輸出,中斷遞迴。
下面介紹一下迴圈的算的方法,不超時。
方法一:
#include<stdio.h>
long long step(int n)
{
if (n <= 2)
return n;
long long a = 1, b = 2, c;
int i = 2;
for(i=2;i<n;i++)//後一項等於前兩項之和
{
c = a + b;
a = b;
b = c;
}
return c;
}
int main()
{
int x,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&x);
printf("%lld\n", step(x));
}
return 0;
}
講兩個坑點,這個step函式要設定成long long
方法二:
遞迴的方法
遞迴的核心就是,return。代表著子問題和原本問題的關係。在這題中,n個臺階的跳法等於n-1個臺階的跳法,加上n-2的臺階的跳法,相當於,我從n的臺階退到n-2階的臺階,可以退一步得到n-1階,也可以是退兩步到n-2階。
遞迴的結束情況,這題是,當只有一個臺階時只有一種走法,兩個臺階的時候兩種走法。
#include <stdio.h>
long long f[500]={0};
long long count(int n)
{
if(f[n]==0)
{
if(n==1||n==2)
return n;
else
return count(n-1)+count(n-2);
}
else
return f[n];
}
int main()
{
int T,n;
long long temp;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
if(f[n]==0)
{
temp=count(n);
f[n]=count(n);//記錄算過的數
}
else
temp=f[n];
printf("%lld\n",temp);
}
return 0;
}
這是改進後的遞迴,加了判斷,但是還是沒過最後一個點,但是在除錯的時候,你從40-50這十一個點是可以算出來50的,而且速度很快,說明,加的判斷生效了。可以返回之前算過的數。
其實,這個題還是個斐波那契數列 (1)1 2 3 5 8 13 21…後一項是前兩項之和,和兔子繁殖的題目也是一樣的,感興趣的可以去搜搜。