遞推與遞迴

2021-10-09 13:34:06 字數 3256 閱讀 8549

2. 例題

2.2 遞迴

遞推強調當前狀態與前乙個狀態的關係,一種考察類似動態規劃的思維處理,另一種考察思維:當前狀態確定後,後繼的所有狀態全部確定。

遞迴的處理思路就算當前狀態取決於子狀態的情況,求當前狀態需要先計算出子狀態後才能決定。

2.1.1 思維遞推

acwing95費解的開關

題意:25盞燈排成乙個5x5的方形。每乙個燈都有乙個開關,遊戲者可以改變它的狀態。每一步,遊戲者可以改變某乙個燈的狀態。遊戲者改變乙個燈的狀態會產生連鎖反應:和這個燈上下左右相鄰的燈也要相應地改變其狀態。用數字「1」表示一盞開著的燈,用數字「0」表示關著的燈。給定n次遊戲的初始狀態,編寫程式判斷遊戲者是否可能在6步以內使所有的燈都變亮。∑

n\sum_{}n

∑​n<= 500

題解:通過分析可以知道當前行的狀態取決於下一行的按燈方式,而下一行的按燈方式卻決於當前行的狀態。也就是說一旦當前行的狀態確定了,下一行怎麼按燈也決定了,往後遞推,那麼所有燈的狀態也決定了。因此,只需要遍歷第一行可能出現的情況,然後就可以發現所有的狀態,然後判斷第5行是否全為1即可。

**:

#include

using

namespace std;

int dx=

, dy=

;int n;

char g[10]

[10], backup[10]

[10];

// 模擬按鍵

void turn (

int x,

int y )

return;}

intmain()

}// 判斷最後一行是否全為1

bool is_success =

true

;for

(int i =

0; i <5;

++i)

if(g[4]

[i]==

'0')

// 全為1,則更新答案

if(is_success) ans =

min(ans, step)

;memcpy

(g, backup,

sizeof backup);}

if(ans <=

6) cout << ans << endl;

else cout <<-1

<< endl;

}return0;

}

codeforces round #658 (div. 2) b. sequential nim

題意:兩個人玩博弈論遊戲,有許多堆石頭,每堆石頭的數目都大於等於1,每次只能從第一堆石頭取,可以取任意個正整數的石頭,一旦不能取石頭那麼就輸了。一開始第乙個人先取,如果第乙個人最後能贏,輸出first;如果第二個人最後能贏,輸出second。∑

n\sum_{}n

∑​n<= 105

題解:如果當前石頭數大於1,那麼當前這個人可以選擇是否交換先後手;如果當前石頭數字1,那麼當前這個人必須交換先後手。因此,一旦出現第乙個大於n的石頭數目,當前這個人就可以根據後面的石頭數,找到最優策略,然後取勝(當前如果是k>1,那麼可以根據後面的石頭確定一種獲勝狀態),因此只需要計算出現第乙個大於1的石頭前面1的個數,如果是奇數,那麼second,否則first(奇數說明到second拿這堆石頭);如果全為1,那麼奇數個1輸出first,否則second(奇數說明一直交換先後手,然後又回到first)

**

#include

using

namespace std;

intconst n =

2e5+10;

int t, a[n]

;int n;

intmain()

return0;

}

2.2.4 思維最小步數

acwing1208. 翻硬幣

題意:一開始給定兩個字串a和b,字串由』*'和』o』組成。每次變化可以將相鄰的兩個字元同時變化(*->0, 0->*),問最少多少次變化可以將a變成b?字串a、b的長度均小於等於100.

題解:題目咋一看是最小步數模型,但是n能到達100,bfs最小步數必然超時。考慮每次變化的關係:每次變化將相鄰的兩個字元反轉,相當於異或操作。對於異或操作來說,異或奇數次可以規約到1次,異或偶數次可以規約到0次,同時異或沒有先後順序之分。因此,對於所有的變化來說,相當於有n個開關,每個開關控制a[i]和a[i+1]。每個開關只有按和不按兩種情況,要求最小的步數,只需要奇數次都規約到1次,偶數次都規約到0次,然後按下的開關是必須的即可。因此,從前往後掃瞄,如果a[i]!=b[i],那麼需要按下開關i,然後把a[i]和a[i+1]反轉,這樣每次按下都是必須的,也就是最少的步數。

**:

#include

using

namespace std;

string s, e;

void

turn

(int x)

intmain()

cout << res << endl;

return0;

}

2.1.2 dp類遞推acwing 92遞迴實現指數型列舉

題意:從 1 ~ n 這 n 個整數中隨機選取任意多個,輸出所有可能的選擇方案。1 ≤ n ≤ 15

題解:n只有15,使用二進位制表示每個數字是否被選即可

**:

#include

using

namespace std;

int n;

void

dfs(

int cur,

int num)

cout << endl;

return;}

dfs(cur +

1, num <<1)

;dfs

(cur +

1, num <<1|

1);return;}

intmain()

遞推與遞迴

遞推與遞迴 遞推像是多公尺諾骨牌,遞迴是大事化小。遞推的效率更高 遞推 斐波那契數列 例 母親為兒子的四年大學學費準備了一筆存款,兒子每月月底取下月生活費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...