記憶化搜尋專題

2021-10-02 13:49:56 字數 1886 閱讀 3152

0.前言

有些時候樸素深蒐會出現超時情況,所以誕生出一種記憶化搜尋的dfs,其實它也是dfs,只不過在dfs的過程中,新增了賦值的過程,這個賦值的過程就叫做記憶。這裡面會根據一些題目來講解記憶化搜尋

1.樣例分析

1.1 題目 絡谷 p1434滑雪

1.2分析

1.3**

#include

using

namespace std;

const

int maxn =

105;

int n,m;

//行列

int arr[maxn]

[maxn]

;//初始的二維序列

int dis[maxn]

[maxn]

;// dis[i][j]表示(i,j)能夠滑行的最遠距離

intgetmax

(int a,

int b,

int c,

int d)

//計算(x,y)能夠滑行的最遠距離sum

//prior表示上乙個數是多少

intdfs

(int x,

int y,

int prior)

if(dis[x]

[y]!=0)

prior = arr[x]

[y];

dis[x]

[y]=

getmax

(//3.返回四個中的最大值,並賦值給dis[x][y]

dfs(x-

1,y,prior)

,dfs

(x,y+

1,prior)

,dfs

(x+1

,y,prior)

,dfs

(x,y-

1,prior))+

1;//4.返回最後的計算結果(為main函式中的tempdis服務)

return dis[x]

[y];

}int

main()

}for

(int i =

0;i}

cout << maxdis<<

"\n"

;}

1.4 測試用例:
3 3 

1 1 3

2 3 4

1 1 1

4

2.反例分析

是不是什麼情況都適合使用記憶化搜尋呢?肯定不是!

今天在寫到絡谷的一道題【

[usaco08jan]牛大賽cow contest 】時,想著是不是可以使用記憶化搜尋。舉例如下。

輸入樣例:奶牛4打敗了2,2又打敗了1,5打敗了2

這樣我們就可以記錄win[1]=0,win[2]=1,win[4]=2。等第搜尋5時,發現2已經搜尋過了,直接返回win[2]+1 = 2,這樣就算出來了win[5]=2。但是這樣真的合適嗎?就拿題中給出的測試用例:

5 5

4 34 2

3 21 2

2 5

這時記憶化搜尋就行不通了,原因是會 出現重複計算。

假設先計算奶牛2,發現奶牛2勝過的牛有1頭(即win[2]=1)。

計算3時,2已經計算過了,直接返回win[2]+1 = 2;計算4時,因為4即可到2,又可到3,且他們都已經訪問過了,所以有win[4] += (win[2]+1) = 3;win[4] += (win[3]+1) =5;就產生了重複計算的問題。

記憶化搜尋

演算法上依然是搜尋的流程,但是搜尋到的一些解用 動態規劃 的那種思想和模式作一些儲存。一般說來,動態規劃總要遍歷所有的狀態,而搜尋可以排除一些無效狀態。更重要的是搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求...

記憶化搜尋

記憶化搜尋 演算法上依然是搜尋的流程,但是搜尋到的一些解用動態規劃的那種思想和模式作一些儲存。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求解乙個狀態,就將它的解儲存下來,以後再次遇到這個狀態的時候,就不必重新求解了。例1.題目描述 給從左至右排好隊的小朋友們分糖果,要求 1.每個小朋友都...

記憶化搜尋

原文 感謝作者。一.動態規劃 動態規劃 dynamic programming 與 分治思想 有些相似,都是利用將問題分 為子問題,並通過合併子問題的解來獲得整個問題的解。於 分治 的不同之處在 於,對於乙個相同的子問題動態規劃演算法不會計算第二次,其實現原理是將每乙個計算過的子問題的值儲存在乙個表...