動態規劃之記憶化搜尋

2021-08-21 14:38:12 字數 2098 閱讀 1542

一. 動態規劃

動態規劃(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)

動態規劃之記憶化搜尋

以 noip 2005 採藥 為例 山洞裡有 m 株不同的草藥,採每一株都需要一些時間 t i 每一株也有它自身的價值 v i 我會給你一段時間 t,在這段時間裡,你可以採到一些草藥。讓採到的草藥的總價值最大。我不會動態規劃,只會搜尋,我就會直接寫乙個粗暴的dfs int n,t int tcost...

動態規劃 記憶化搜尋

記憶化搜尋顧名思義是在搜尋的過程中通過記錄搜尋的中間狀態從而達到減少重複搜尋的方法,通常用在搜尋樹 現重複子節點的情況。例題 滑雪 給定乙個r行c列的矩陣,表示乙個矩形網格滑雪場。矩陣中第 i 行第 j 列的點表示滑雪場的第 i 行第 j 列區域的高度。乙個人從滑雪場中的某個區域內出發,每次可以向上...

動態規劃 記憶化搜尋(滑雪)

給定乙個r行c列的矩陣,表示乙個矩形網格滑雪場。矩陣中第 i 行第 j 列的點表示滑雪場的第 i 行第 j 列區域的高度。乙個人從滑雪場中的某個區域內出發,每次可以向上下左右任意乙個方向滑動乙個單位距離。當然,乙個人能夠滑動到某相鄰區域的前提是該區域的高度低於自己目前所在區域的高度。下面給出乙個矩陣...