從斐波那契數列開始,0基礎入門遞迴和動態規劃

2021-10-22 01:55:14 字數 3297 閱讀 3290

reference:

為什麼你學不會遞迴?告別遞迴,談談我的一些經驗

告別動態規劃,連刷40道動規演算法題,我總結了動規的套路

動態規劃 **理解

個人認為,遞迴和動態規劃,尤其能體現計算機程式設計的魅力。

使用斐波那契數列引入了動態規劃的概念

斐波那契數列的是這樣乙個數列:1、1、2、3、5、8、13、21、34….,即第一項 f(1) = 1,第二項 f(2) = 1……,第n 專案為 f(n) = f(n-1) + f(n-2)。求第 n 項的值是多少。

大家大概在小學的時候就接觸過類似於這樣的,找數學規律的題目。而在計算機程式設計中,這裡的「規律」,就是我們編碼的核心和基本。也叫做「子問題」「狀態」

例如上述的斐波那契數列,他的」規律「就是f(n) = f(n-1) + f(n-2)。

表示如下::

f (n

)=1 & \text\\ f(n-1) + f(n-2)& \text \end

f(n)

=二、找到「回歸」條件,也就是函式的結束條件。

public

intfiboseq

(int n)

}

三、補充遞迴函式核心「傳遞」規律

public

intfiboseq

(int n)

// n的傳遞規律

return

fiboseq

(n-1)+

fiboseq

(n-2);

}

我們可以親切的把斐波那契數列問題看成雞生蛋的問題。小雞家族的每乙隻雞都有乙個使命,那就是自己生的蛋必須比前兩隻雞生的蛋的總和。

現在我們是第n只小雞,我們不知道我們應該生多少隻蛋,於是我去問前面兩隻雞n-1n-2

return

fiboseq

(n-1)+

fiboseq

(n-2

);

n-1只小雞和第n-2只小雞說我也忘了我生了多少蛋了,我去問問我前面那兩隻雞。

進入到

fiboseq

(n-1)+

fiboseq

(n-2

);

的內部:

fiboseq

(n-1

)://第n-1只小雞去問自己前面的第(n-1)-1只小雞和第(n-1)-2只小雞

return

fiboseq

((n-

1)-1)+

fiboseq

((n-

1)-2);

//第n-2只小雞去問自己前面的第(n-2)-1只小雞和第(n-2)-2只小雞

fiboseq

(n-2

):return

fiboseq

((n-

2)-1)+

fiboseq

((n-

2)-2

);

直到找到了小雞祖宗,也就是第1只和第2隻雞,

fiboseq(2

):public

intfiboseq

(int n)

。。。}

fiboseq(1

):public

intfiboseq

(int n=2)

。。。}

好的,那麼現在第三隻雞知道自己生了1+1=2隻雞了,第四隻雞也知道自己生了1+2=3隻雞啦,第五只也知道。。。最後來到了第n只,也就知道了自己生了多少隻雞啦!

由此可見程式設計是多麼的神奇,如此複雜的一層一層向下尋找,又最後一層一層的向上回傳,用寥寥幾行**就可以表示。

同時,我們也可以總結出,當資料向下層尋找的時候若規律相同,即可以無限地呼叫起自己所在的函式的時候,就可以用遞迴。

以n=8為例,上面的函式可以簡化為下面的模型:

在這裡插入描述

此時的1⃣️號?和2⃣️號?內心os:你們這群雞崽子能不能記點事兒啊?比如3⃣️號?,你來問自己生了多少蛋問了七次,牛教三次都知道打轉呢!(此段責罵的reference是我的媽媽)。

但是這時候的3⃣️號?內心非常的委屈:可是人家只是乙隻雞,記不住那麼多事情嘛。所以,不如我把我生了多少隻雞寫下來,方便四號檢視,四號之後是五號。。。這樣我就只用問兩個雞祖宗一次,就不會被罵啦!

於是乎,就有了「動態規劃」,與「遞迴」「自上而下」不同,「動態規劃」「自下而上的」。在函式裡,我們用for迴圈,來實現n的向上傳遞。

public

intfiboseq

(int n)

int[

] dp =

newint

[n+1];

//設定乙個快取空間

//dp[0] = 0;

dp[1]

=1; dp[2]

=2;// 從三號雞開始往上遞送訊息

for(

int m=

3, m<=n; m++

)return dp[n]

;}

對於乙個遞迴結構的問題,如果我們在分析它的過程中,發現了它有很多「重疊子問題」,雖然並不影響結果的正確性,但是我們認為大量的重複計算是不環保,不簡潔,不優雅,不高效的,因此,我們必須將「重疊子問題」進行優化,優化的方法就是「加入快取」,「加入快取」的乙個學術上的叫法就是「記憶化搜尋」。

另外,我們還發現,直接分析遞迴結構,是假設更小的子問題已經解決給出的實現,思考的路徑是「自頂向下」。但有的時候,「自底向上」的思考路徑往往更直接,這就是「動態規劃」,我們是真正地解決了更小規模的問題,在處理更大規模的問題的時候,直接使用了更小規模問題的結果。

一維動態規劃練習題

leetcode

#70 爬樓梯

#746. 使用最小花費爬樓梯

#198 打劫家舍

#413 等差數列劃分

從斐波那契數列(Fibonacci)入門遞迴和遞推

斐波那契數列,又稱 分割數列,指的是這樣乙個數列 0 1 1 2 3 5 8 13 21 在數學上,斐波納契數列以如下被以遞迴的方法定義 f0 0,f1 1,fn f n 1 f n 2 n 2,n n 在現代物理 準晶體結構 化學等領域,斐波納契數列都有直接的應用,為此,美國數學會從1960年代起...

斐波那契數列 斐波那契數列python實現

斐波那契數列 fibonacci sequence 又稱 分割數列 因數學家列昂納多 斐波那契 leonardoda fibonacci 以兔子繁殖為例子而引入,故又稱為 兔子數列 指的是這樣乙個數列 1 1 2 3 5 8 13 21 34 在數學上,斐波納契數列以如下被以遞推的方法定義 f 1 ...

迴圈斐波那契數列 斐波那契數列應用

什麼是斐波那契數列 斐波那契數列指的是這樣乙個數列 1,1,2,3,5,8,13,21,34,55,89,144 這個數列從第3項開始,每一項都等於前兩項之和 台階問題 有一段樓梯有10級台階,規定每一步只能跨一級或兩級,要登上第10級台階有幾種不同的走法?這就是乙個斐波那契數列 登上第一級台階有一...