Note 遞推與遞迴

2022-09-09 22:57:28 字數 3046 閱讀 9412

2021/11/16:修了一下以前的 \(\latex\)

遞推演算法是一種用若干步可重複運算來描述複雜問題的方法。遞推是序列計算中的一種常用演算法。通常是通過計算前面的一些項來得出序列中的指定項的值。

有很多遞推的基礎題都是以斐波那契數列為基礎的,例如我們的鋪磚系列:

鋪磚1遞推式就是我們原始的斐波那契數列:

邊界條件:\(a_1 = 1, a_2 = 1\)

遞推式:\(a_i = a_ + a_\)

其他的類似題也不過是以此遞推式變形罷了

其實跟上面也差不多

邊界條件:\(a_1 = 1\)

遞推式:\(a_i = a_×2+1\)

平面分割1

這道題目其實看圖都能看出規律來

2,4,8,14.......

\(code\)

#include using namespace std;

int main() ;

a[1] = 2;

int tot = 0;

for (int i = 2; i <= n; i++)

cout << a[n];

return 0;

}

終於到我們的 \(catalan\) 了,這是考試最常考的一類,很多題目都以此為模板,進行遞推。比如樹屋階梯。。。

我們就以經典題目凸n邊形的不同劃分方式為例。

我們設凸 \(n\) 邊形的不同劃分方式有 \(a_n\) 種。給凸 \(n\) 邊形的每乙個角都編上號,從 \(1\) 到 \(n\) 。現在固定住 \(1\) 和 \(n\) 角,在其它頂點上任意選乙個頂點 \(j\),連線 \(1\) 、 \(j\) 和 \(n\) 、 \(j\) ,發現把這個凸n邊形分成了三個形狀,第乙個是乙個 \(j\) 邊形,第二個是乙個三角形,第三個是乙個 \(n - j + 1\) 邊形。我們知道 \(j\) 邊形有 \(a_j\) 種不同劃分方式, \(n - j + 1\) 邊形有 \(a_\) 種不同劃分方式,所以通過乘法原理,所以 \(i\) 邊形就有 \(a_ × a_j\) 種劃分方式。

邊界條件:\(a_1 = a_2 = 1\)

遞推式:

\(a_i = \displaystyle\sum_^ a_×a_j\)

例題:合理放球

這是一道典型的二維遞推

我們可以設 \(a_\) 表示 \(i\) 個球放入 \(j\) 個箱子裡面

我們發現;

當 \(i < j\) 或者 沒有箱子的時候肯定就沒法放,所以 \(a_ = 0\);

當 \(i == j\) 時,當且僅當只有一種方案,故 \(a_ = 1\)

當 只有乙個箱子是肯定只有一種,故 \(a_ = 1\)

當 只有乙個球時,前面已經判斷過不止乙個箱子所以不管怎麼弄也只有 \(0\) 種方案

如果上述條件都不滿足,就

\(a_ = a_ + j × _\)

\(code\)

#include using namespace std;

int main() ;

for (int i = 0; i <= n; i++)

}cout << dp[n][m];

return 0;

}

好了,遞推部分就結束了,下面我們就將迎來我們的遞迴演算法遞迴是啥,能吃嗎?

遞迴就是在函式體內部呼叫自己本身的一種演算法(非官方定義)

我們就拿上文提到的斐波那契數列舉例吧!

先給出**:

#include int f(int n) 

int main()

遞迴最重要的部分叫做遞迴出口。例如,以上**的遞推出口就是

if (n == 1) return 1;

else if (n == 2) return 2;

如果乙個遞迴沒有遞迴出口的話,那會是相當恐怖的。。。有興趣的同學可以執行一下以下**:

#include #include int f(int n) 

int main()

明白了遞迴的基本用法過後,下面我們就來用遞迴來實現 \(n\) 的全排列。

(什麼\(?\)全排列還要用手打,不是有 \(next\_permutation\) 嗎\(?\))

這算得上一道簡單的回溯了。

\(code\)

#include using namespace std;

int n;

char a[15], st[15];

bool b[15] = {};

int print();

int search(int t) else

search(t + 1);

b[i] = false;}}

}int print()

printf("\n");

}int main()

什麼???剛剛寫的斐波那契數列超時了!!!

我們可以輸出 \(n\) 看一下

我們發現,\(n\) 重複計算了很多次,這樣就很容易超時。所以我們可以用乙個陣列來儲存 \(f(n)\) 的值,這樣避免了很多重複計算。

就像這樣:

#include int data[55];

int f(int n)

}int main()

這就是記憶化遞迴,在搜尋 的時候會起到很大作用。

若有錯誤的地方, 請各位大佬指出

遞推與遞迴

遞推與遞迴 遞推像是多公尺諾骨牌,遞迴是大事化小。遞推的效率更高 遞推 斐波那契數列 例 母親為兒子的四年大學學費準備了一筆存款,兒子每月月底取下月生活費1000元。銀行年利率為 1.71 畢業時連本帶息要取出 1000 元。則要存入多少錢。include define rate 0.0171 in...

遞推與遞迴

遞迴 將問題規模為n的問題,降解成若干個規模為n 1的問題,依次降解,直到問題規模可求,求出低階規模的解,代入高階問題中,直至求出規模為n的問題的解。遞推 構造低階的規模 如規模為i,一般i 0 的問題,並求出解,推導出問題規模為i 1的問題以及解,依次推到規模為n的問題。遞迴包括回溯和遞推兩個過程...

遞迴與遞推

1 遞迴與遞推的定義 前者是 後者是對以前的問題進行計算,以得出當前問題的大結果。2 它們的典例和運用遞迴 遞推dfs,搜尋與回溯 動態規劃 用遞推能做的,記憶化搜尋定能夠實現 遞推僅能求方案數,求具體方案需用遞迴 3 各種關於遞推的例題 爬樓梯 數樓梯 兔子問題 includeusing name...