我在dp這塊一直挺亂的,做2023年校招真題(輸出1,2,3...n中和等於m的所有可能組合)的時候,當時用的dfs,做完之後感覺怎麼跟dp有點像呢,然後就搜了一下大佬們都怎麼看這個問題的,結果確實是有那麼一點聯絡的
以數字三角形為例:給出乙個數字三角形,從頂部到底部有很多路徑,求路徑最大和。如:7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
樸素dfs的想法就是從(0,0)開始求下一步(向下或者右下)的最大值加上當前點的值
int dfs(int x,int y) //表示從第x行,第y個數往下走可以得到的最大價值和,dfs(0,0)即為本題解。
可以看出樸素dfs有大量的重複計算,比如對於中間的一點,他既是某一點的下又是另一點的右下。
記憶化dfs就是把上面dfs的結果儲存起來,要用的時候直接使,不需要再來一次遞迴:
//result陣列儲存中間結果
int dfs(int x,int y)
綜上,樸素dfs和記憶化dfs都是基於遞迴思想計算,而利用遞迴的條件有兩個:一是可以把待解決問題轉化成乙個新問題,而這個新問題的解決方法不變,但是問題規模在減小;二是要有遞迴出口。
比如這裡我們通過dfs(x+1,y)和dfs(x+1,y+1)去求(x,y),x大於行數的時候退出。
dp動態規劃直接用陣列儲存狀態,在狀態和狀態之間實現轉移。
//numcount即陣列三角形的行數
for(int i = numcount - 1; i >= 0; i--)
for(int j = 0;j <= i; j++)
//result[i][j] = max(result[i+1][j],result[i+1][j+1]) + num[i][j];
result陣列空間比三角形大1,全初始化為0,dp的計算過程是先算三角形的最後一行result[numcount-1][j],result[i+1][j]從實際意義講不存在,這裡等於1,所以這一行計算結果都是本身,然後算上一行直到(0,0),得到問題最終解。
可以看出記憶化dfs和dp動態規劃都儲存了中間結果,不同的是兩者的想法正好是反的,dp從下往上算,記憶化dfs因為是遞迴從上往下算。
dfs 記憶化 滑雪
傳送門 題意 給定乙個r行c列的矩陣,表示乙個矩形網格滑雪場。矩陣中第 i 行第 j 列的點表示滑雪場的第 i 行第 j 列區域的高度。乙個人從滑雪場中的某個區域內出發,每次可以向上下左右任意乙個方向滑動乙個單位距離。當然,乙個人能夠滑動到某相鄰區域的前提是該區域的高度低於自己目前所在區域的高度。資...
滑雪 DFS 記憶化搜尋
michael喜歡滑雪百這並不奇怪,因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待公升降機來載你。michael想知道載乙個區域中最長的滑坡。區域由乙個二維陣列給出。陣列的每個數字代表點的高度。下面是乙個例子 1 2 3 4 5 16 17 ...
帕斯卡遊記 記憶化dfs
問題描述 nxn遊戲板上裝有整數,每平方乙個非負整數。目標是沿著板子的左上角到右下角的任何合法路徑行進。任何乙個正方形中的整數表示距該位置必須多大的步幅。如果步長將提前離開遊戲板,則禁止沿該特定方向前進。所有步驟都必須在右側或底部。請注意,0是乙個死角,會阻止進一步的進展。考慮圖1所示的4 x 4板...