記憶化搜尋

2021-08-07 05:37:42 字數 2116 閱讀 8164

原文: 感謝作者。

一. 動態規劃

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

二. 記憶化搜尋

我們常見的動態規劃問題,比如流水線排程問題,矩陣鏈乘問題等等都是「一步接著一步解決的」,即規模為 i 的問題需要基於規模 i-1 的問題進行最優解選擇,通常的遞迴模式為dp(i)=optimal。而記憶化搜尋本質上也是dp思想,當子問題a和子問題b存在子子問題c時,如果子子問題c的最優解已經被求出,那麼子問題a或者是b只需要「查表」獲得c的解,而不需要再算一遍c。記憶化搜尋的dp模式比普通模式要「隨意一些」,通常為dp(i)=optimal(dp(j)), j < i。

三. 滑雪問題

上圖顯示為r*c的雪場,r是行數,c是列數。圓圈內的數字表示的是雪場的海拔高度h,根據常識我們知道,滑雪只有從上往下滑行才可能滑的動,現在我們想要求出能夠滑行的最長距離,上面的例子我們可以很直接判斷出25-24-......-1這個順時針方向螺旋的滑雪方式可以滑的最遠。

那麼這個問題如何用程式設計來實現呢?我們發現這是乙個典型的遞推,dp(i, j)表示從座標(i,j)出發所能滑行的最大長度,且有:dp(i, j)=optimal+1。下面貼上原始碼。

#include#include#include#includeusing namespace std;

const int max_size=110;

int r,c;

int dir[4][2]=,,,};

int h[max_size][max_size],dp[max_size][max_size];

int inmap(int x,int y)

int max2(int a,int b,int c,int d)

int dfs(int i,int j)

nx=i+dir[1][0]; ny=j+dir[1][1];

if(inmap(nx,ny))

nx=i+dir[2][0]; ny=j+dir[2][1];

if(inmap(nx,ny))

nx=i+dir[3][0]; ny=j+dir[3][1];

if(inmap(nx,ny))

dp[i][j]=max2(up,down,left,right)+1;

return dp[i][j];

}int main()}。實現**如下:

#include#include#includeusing namespace std;

const int max_size=50;

const int inf=1<<30;

int price[max_size],dp[max_size];

int n;

int dfs(int n)

dp[n]=mmax;

return dp[n];

}int main()

}

五. 01揹包問題問題描述: 有n件物品和乙個重量為m的揹包。(每種物品均只有一件)第i件物品的重量是w[i],價值是p[i]。求解將哪些物品裝入揹包可使價值總和最大。思路也很簡單,直接看**

#include#include#includeusing namespace std;

const int max_size=50;

const int inf=1<<30;

int p[max_size],w[max_size],dp[max_size][max_size];

int n,v;

int dfs(int i,int v)

int main()

}

六. 總結

dfs(problem a)

記憶化搜尋

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

記憶化搜尋

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

記憶化搜尋

時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld 給定兩個長度為n的整數列a和b,每次你可以從a數列的左端或右端取走乙個數。假設第i次取走的數為a x,則第i次取走的數的價值v i bi a x,現在希望你求出 v...