C語言入門筆記 第六講 遞迴之青蛙跳台階

2021-10-16 17:46:30 字數 2165 閱讀 5239

昨天晚上睡前看了一下問題描述,講的是乙隻青蛙跳n個台階,一次可以跳一階,一次也可以跳兩階,問一共有多少種跳法。

當時我的思路是:

先想了n=1和n=2的情況,

當n=1時,只有一種跳法--即1;

當n=2時,有兩種跳--1 1或者2

因為小青蛙一次可以跳1或者2,

所以我想把n=1和n=2的情況作為遞迴出口。

比如,n=3的情況,就相當於小青蛙跳了乙個2,和乙個1

並且他們之間是可以有順序的,

一共兩種順序:

小青蛙先跳乙個n=1,再跳乙個n=2;

小青蛙先跳乙個n=2,再跳乙個n=1。

然而,問題出現了,當小青蛙跳n=2時,選擇了1 1跳法,

那麼此時上述兩種順序跳出來的結果都是1 1 1,

說明有重複。

當n取更大的時候,這種重複更多,我們需要把它減去。

想到這的時候,我就知道,我的想法肯定錯了。

遞迴演算法是為了讓人好理解,犧牲一部分機器的執行時間,來換取程式的更強可讀性。

我這想法已經把自己繞進去了,顯然是不可行的。

下面一起來學一學這個問題吧!

【一、思路 中會闡述清楚為什麼不會出現重複問題】

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

當n=1時,一共有一種跳法(1)

當n=2時,一共有兩種跳法(1,1),(2)

當n>2時,

這裡我們以n=3為例:

由於很好列舉,我們直接給出跳法,

一共3種:

(1,1,1)

(1,2)

(2,1)

如果我們去掉跳的第一次,

如(1,1,1)一共跳了3次,去掉第一次跳的1階,剩下的結果為(1,1)

同理,剩下兩種跳法去掉第一次後的結果分別為(2)和(1)。

我們把他們放在一起看一下:

(1,1)

(2)(1)

再觀察:這前兩種:(1,1)和(2)不正好是n=2時的跳法嗎?

最後一種,也正好是n=1的跳法。

我們再來列舉一下n=4的情況:

(1,1,1,1)

(1,1,2)

(1,2,1)

(2,1,1)

(2,2)

一共五種。

以第一步跳的是1還是2,我們來划上分割線:

(1,1,1,1)

(1,1,2)

(1,2,1)

------分割線-----------上為a段,下為b段

(2,1,1)

(2,2)

然後,我們對a段進行去掉第一步的處理:

(1,1,1)

(1,2)

(2,1)

是n=3的情景。

同理,對b段進行去掉第一步的處理:

(1,1)

(2)是n=2的情景。

n=4可以劃分為n=3和n=2兩個子問題,而n=3又可以劃分為n=2和n=1兩個子問題,

也就是說,n=4  -->  n=3 + n=2  -->  n=2 + n=1 + n=2

而n=1和n=2就是我們的初始條件,遞迴出口,

所以完成了遞迴。

本題和斐波那契數列有異曲同工之妙。

回過頭來,我們再想想一開始我的想法出現的問題:是否會導致重複?

答案是不會的。

因為我們是以第一步是1還是2來劃分子問題,這裡的2是一次跳兩階,很明顯,第一步已經不一樣了,所以不會出現重複的問題。

用概率論的思想就是先分類

分第一步跳1次還是2次兩大類

分類用加法;

而對於第一步跳一次的情景,

它又和後面的步驟形成了分步執行問題

分步用乘法。

但是它自身就只有一步,

所以相當於是

這裡我們就把是否會出現重複問題給講清楚了。

int frog_jump(int n)

int main()

本樣例**程式執行結果為8,

測試多組樣例,滿足題意。

C語言入門筆記 第五講 迴圈語句之for

for迴圈是用的最多的迴圈,其次是while,最後是do while。for 表示式1 表示式2 表示式3 迴圈語句 表示式1表示式1為初始化部分,用於初始化迴圈變數的。表示式2表示式2為條件判斷部分,用於判斷 迴圈時候終止。表示式3表示式3為調整部分,用於迴圈條件的調整。我們來看乙個例子 使用fo...

C語言入門筆記 第五講 迴圈語句之while

我們已經掌握了,if語句。當條件滿足的情況下,if語句後的語句執行,否則不執行。但是這個語句只會執行一次。但是我們發現生活中很多的實際的例子是 同一件事情我們需要完成很多次。那我們怎麼做呢?c語言中給我們引入了 while,for,do while 三種語句,可以實現迴圈。while 語法結構 wh...

嵌入式c 軟體開發筆記 第六講

對檔案進行讀寫操作 讀檔案operator int get istream get int istream get char int n,char deli istream getline char int n get vs getline get 和getline 最大的區別就是,get 遇到界定...