1. 程式人生 > 其它 >遞迴系列---1.青蛙跳臺階 (10分)

遞迴系列---1.青蛙跳臺階 (10分)

技術標籤:PTAc語言遞迴演算法

遞迴系列—1.青蛙跳臺階 (10分)

在PTA上刷題,遇到這個問題,高三的時候聽數學老師講過,當時不知道什麼是遞迴,現在明白了,覺得有點意思。

題意
一隻青蛙一次可以跳上 1 級臺階,也可以跳上2 級。求該青蛙跳上一個n 級的臺階總共有多少種跳法。

輸入格式:
首先輸入數字n,代表接下來有n組輸入,50>=n>=0,然後每行一個數字,代表臺階數,數字為小於60的整數

輸出格式:
對每一組輸入,輸出青蛙的跳法。

輸入樣例:
3
1
2
3

輸出樣例:
1
2
3

我對於遞迴的理解是,大的問題,可以轉換成相同的,但是規模減少的相同的子問題,並且子問題減少的最小還要有解(遞迴有基準情況)。

常見用遞迴解決的問題有:前n項和,階乘(迴圈也可以),還有著名的漢諾塔問題。一些常見的演算法也有遞迴的思想在裡面,比如快排等等,後續會介紹。
回到這個問題,這個問題想考的是遞迴,但是我遞迴最後一個測試點超時了,後來看了看資料,階梯數小於等於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

型,50時候int 就超了,而且中間變數,a,b;也要設定成 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…後一項是前兩項之和,和兔子繁殖的題目也是一樣的,感興趣的可以去搜搜。