遞迴遞推區別分析與例題總結

2021-10-09 00:25:25 字數 4167 閱讀 1534

例題遞迴例子

漢諾塔問題

倒序輸出正整數

執行過程中自我呼叫,求解過程分為回溯和遞推兩個過程,占用記憶體多(棧數先積累後收縮,有可能爆棧),**簡潔但低效。

尾遞迴和遞迴區別⬇

function story()

function story()

尾遞迴省記憶體、高效(相當於迭代(或者說遞推?))

python無法在語言中實現尾遞迴優化(tail call optimization, tco),所以採用了for, while等特殊結構代替recursive的表述(優化是編譯器幹的,發現尾遞迴結構就給優化了)。

效率比遞迴高,盡量遞推,除非只能遞迴。

一般都是數學題。。重點是找遞推公式(也太好偷懶了吧)

平面分割問題

直線分割平面(基本結論)

如果當前有 n 條直線,新增加一條直線(第 n+1 條直線),可以多出來 n 個交點(新的直線和之前所有的直線都有交點),而多出來 n 個交點對應到可以多出 n+1 個平面(比如從兩條線,又新增一條線時,新的線和兩條線都相交,作用在三個區域上,對這三個區域切分,增加三個平面)。也即:

s n+

1=sn

+(n+

1)=1

+(n+

1)(n

+2)2

s_=s_+(n+1)=1+\frac

sn+1​=

sn​+

(n+1

)=1+

2(n+

1)(n

+2)​

線圈分割平面

設有n條封閉曲線畫在平面上,而任何兩條封閉曲線恰好相交於兩點,且任何三條封閉曲線不相交於同一點,問這些封閉曲線把平面分割成的區域個數。

當平面上已有n-1條曲線將平面分割成an-1個區域後,第n-1條曲線每與曲線相交一次,就會增加乙個區域,因為平面上已有了n-1條封閉曲線,且第n條曲線與已有的每一條閉曲線恰好相交於兩點,且不會與任兩條曲線交於同一點,故平面上一共增加2(n-1)個區域,加上已有的an-1個區域,一共有an-1+2(n-1)個區域。所以本題的遞推關係是an=an-1+2(n-1),邊界條件a1=2。

平面分割變體很多,在短時間內建立遞推關係是難點。

折線分割平面

題目見鏈結⬆

對於折線:設第n-1條折線,把空間劃分的區域為f(n-1),為了增加的區域最多,新增的折線要和之前的n-1條折線的2(n-1)條邊都相交(因為是折線所以每條邊交了兩次),交點數為4(n-1),新增的線段數為4(n-1),射線數為2。但要注意的是,折線本身相鄰的兩線段只能增加乙個區域。新增區域數目為4(n-1)

新增區域圖示⬇

(多乙個線段或射線都產生乙個新區域,除了最左邊那兩條合起來只產生乙個新區域。)

所以有遞推公式:

f(n)=f(n-1)+4(n-1) + 1=2n2-n+1

偷懶方法

這類問題一般都有固定的公式,二維的一般是an2+bn+c,三維的一般是an3+bn2+cn+d。

用待定係數法求出各個係數就ok了。

catalan數 cn=

1n+1

(2nn

)=(2

n)!(

n+1)

!n!c_=\frac\left(\begin 2 n \\ n \end\right)=\frac

cn​=n+

11​(

2nn​

)=(n

+1)!

n!(2

n)!​

斐波那契數列(fibonacci)應用

得到的是遞推式,但只能用遞迴寫,或者優化為dp

兔子繁殖問題

有雌雄一對兔子,每過兩個月便可繁殖雌雄各一的一對小兔子。問過n個月後共有多少對兔子?

設滿x個月時共有兔子f(x)對,滿x-1個月時共有兔子f(x-1)對,第x月當月新生的兔子數目為n對。

fx=n+f(x-1)

n=f(x-2)❗ (即第x-2個月的所有兔子到第x個月都有繁殖能力了)

得fx=f(x-1)+f(x-2)

邊界條件:f0=0,f1=1

由上面的遞推關係可依次得到:

f2=f1+f0=1,f3=f2+f1=2,f4=f3+f2=3,f5=f4+f3=5…

繁殖問題通常與斐波那契數列有聯絡。類似題:母牛的故事。

可得遞推式:

f (n

)=n & n<=4 \\ f(n-1)+f(n-3) & n>4 \end\right.

f(n)

==f_+f_ \quad(a+2<=n<=b)

fn​=fn

−1​+

fn−2

​(a+

2<=n

<=b

)邊界條件為fa=fa+1=1。

漢諾塔問題

法國數學家愛德華·盧卡斯曾編寫過乙個印度的古老傳說:在世界中心貝拿勒斯(在印度北部)的聖廟裡,一塊黃銅板上插著三根寶石針。印度教的主神梵天在創造世界的時候,在其中一根針上從下到上地穿好了由大到小的64片金片,這就是所謂的漢諾塔。不論白天黑夜,總有乙個僧侶在按照下面的法則移動這些金片:一次只移動一片,不管在哪根針上,小片必須在大片上面。僧侶們預言,當所有的金片都從梵天穿好的那根針上移到另外一根針上時,世界就將在一聲霹靂中消滅,而梵塔、廟宇和眾生也都將同歸於盡。

這裡用遞迴更好理解(僅此而已,遞推效率更高),也能求通項公式

以y桿為中介,將前n-1個圓盤從x杆移到z杆(本身就是乙個n-1的漢諾塔問題了!)

將第n個圓盤移到y杆

以x桿為中介,將z桿上的n-1個圓盤移到y杆(本身就是乙個n-1的漢諾塔問題了!)

設f(n)為將n片圓盤所在塔全部移動到另一塔最少總次數;由遞迴演算法可知:f(1) = 1;當n>1時,f(n) = f(n-1) + 1 + f(n-1)。計算可得通項公式:f(n)=2n-1. (n>0)

有了遞推公式f(n)=2*f(n-1)+1,遞迴就完了(數太大了,注意資料型別是ull)

關於ull:

unsigned long long型別是目前c語言中精度最高的資料型別,可以用來表示20以內的階乘資料,20以外的自測。

unsigned long long的精度是64位,double或者long double 雖然也占有8個位元組,但是他們的實際精度只有53位。

使用 %llu 就可以列印乙個unsigned long long資料了

#include

unsigned

long

long

hanoi

(int n)

intmain()

倒序輸出正整數

先進後出,可以用棧實現(並不會)

例:給出正整數 n=12345,以各位數的逆序形式輸出,即輸出54321。

遞迴思想:首先輸出這個數的個位數,然後再輸出前面數字的個位數,直到之前沒數字。

數列的遞迴表示式:

f (n

)=\operatorname(n \% 10), & \mathrm<10 \\ \operatorname(n \% 10) ; f(n / 10), & \mathrm>=10 \end\right.

f(n)

=python最省事的就是切片:

print(str(s)[: : -1])

遞迴與遞推的區別

今天在學習遞迴和動態規劃時有點迷糊了,兩者無法區別,在網上差了下,總接如下 首先要清楚,遞推就是迭代。1.遞迴其實就是利用系統堆疊,實現函式自身呼叫,或者是相互呼叫的過程.在通往邊界的過程中,都會把單步位址儲存下來,知道等出邊界,再按照先進後出的進行運算,這正如我們裝木桶一樣,每一次都只能把東西方在...

遞迴遞推總結

1.遞迴比較好理解,而且就是自己調自己,就是把大問題轉換成小問題,最重要的就是把終止條件和遞迴方程。比較典型的就是 全排列和半數集 半數集和全排列都是一位一位的遞迴,半數集的結束條件就是等於1,全排列是位數到了最大。2.遞迴感覺比較靈活,就是要完成一件事需要多個步驟,每個步驟都進行不一樣的處理,經典...

遞迴遞推總結

遞迴是大問題轉化為小問題,不斷呼叫自身或不斷間接呼叫的一類演算法。遞迴演算法的關鍵是 1.要找出大問題和小問題的聯絡 遞迴定義。2.遞迴終止條件。遞推是一種用若干步可重複運算來描述複雜問題的方法.遞推的關鍵是想出遞推公式,一般遞推公式是從後面向前推,當然也有很多是從中間或者從前向後推。做這些題目主要...