記憶化遞迴入門

2021-10-11 00:22:34 字數 1768 閱讀 1091

初識記憶化遞迴

記憶化遞迴的**實現

題目

題目描述:

乙個有趣的圓環套圓環函式被定義如下:

g(n)=n-g(g(n-1)) (n是正整數)

g(0)=0

請你計算出圓環函式的值。

輸入: 乙個非負整數n,n<=200。

輸出:乙個正整數,即g(n)。

第一次提交 (時間超限83)
#includeusing namespace std;

int a(int k)

int main()

int main()

cout分析

第一次提交的結果是超時,第二次提交通過處理"特殊值"使得提交正確

缺點:假如給的資料中類似197這樣的大數很多,那就要每個都進行處理(if...)

初識記憶化遞迴
1. 原始遞迴:

題目所給的公式 g(n) = n-g(g(n-1)) (n是正整數)

g(g(...)) 是兩層(一層以上)的遞迴, 如果不進行任何處理,則需要重複計算很多步驟

下圖中(...)就是 g(g(i)) 中 g(i) 的值計算好後 代進去,還要繼續進行計算 g(j) 的操作

(其中j是g(i)計算出來的值)

2. 記憶化遞迴:

前提:遞迴中g(g(i))一般 i 要比 g(i) 要小,所以在計算g(g(i)) 時 g(i) 的值可能之前已經計算過了

概念:利用陣列儲存已計算好的資料,res[i] = g(i)

則下次g(g(i))中g(i)的值計算好後 代進去,可以通過res[g(i)]得到g(g(i))的值,大大提高了時間效率

記憶化遞迴的**實現

帶bool visited[max_size] 記錄

#include using namespace std;

#define max_size 2001

int res[max_size]; //res[x] = x - g(g(x - 1)), 即為res[x] == g(x)

bool visited[max_size];

int g(int x)

//記憶化搜尋

if (visited[x])

//標記g(x)已被計算,res[x] 已儲存了 g(x) 的值

visited[x] = true;

return res[x] = x - g(g(x - 1));}

int main()

不帶bool visited[max_size] 記錄
#include using namespace std;

#define max_size 2001

#define mm(a,b) memset(a,b,sizeof(a))

int res[max_size]; //res[x] = x - g(g(x - 1)), 即為res[x] == g(x)

bool visited[max_size];

int g(int x)

//記憶化搜尋, 若res[x] != -1,則代表res[x] 已被更新為 g(i)

if (res[x] != -1)

return res[x] = x - g(g(x - 1));}

int main()

遞迴入門自學

例題 計算給定的n個數的和 分析 顯然當n 0的a 0 為所求,因此可以將前n項可以看做是前n 1 即 a 0,n 2 項的和加上第n項 int sum int a,int n 如上演算法中的sum 在進行遞迴呼叫的時對自身的呼叫最多隻會進行一次,也就是在每一層次上至多只有乙個例項,且構成乙個線性結...

《遞迴入門》之回文

所謂回文字串,就是乙個字串,從左到右讀和從右到左讀是完全一樣的。比如 level aaabbaaa 題目 判斷乙個字串是否為回文 解法 遞迴 遞迴的作用在於把問題的規模不斷縮少,直到問題縮少到能簡單地解決 問 如何縮少問題規模?答 通過觀察可以知道,乙個回文字串其中內部也是回文。所以,我們只需要以去...

C語言 遞迴入門

遞迴是什麼,遞迴就是一種解決問題的方法 程式自身呼叫自身叫做遞迴。它的核心在於 大事化小!先舉幾個例子 1.接受乙個整型值,按順序列印它的每一位。只考慮正數 如 1234 應輸出1 2 3 4 1 先討論如果不遞迴該怎樣處理,一般步驟是這樣的,先判斷這個數是幾位數,然後在記錄下這個數的每一位,最後輸...