動態規劃入門 持續更新

2022-10-09 13:51:11 字數 2373 閱讀 5571

本文通過01揹包問題引入動態規劃,來介紹各種揹包與初等動態規劃問題,持續更新中...

問題概述:有n個重量和價值分別為\(w_i\)和\(v_i\)的物品。從這些物品中挑選出總重量不超過\(w\)的物品,求所有挑選方案中價值總和的最大值。(下標從1開始)

樣例:

\[input:n = 4,w = 10,(w,v) =

\]\[output:12(選擇2,4號物品)

\]思路引入:我們最容易想到的方案是暴力搜尋,即對所有物品是否放入揹包進行搜尋。**如下:

int n, w;

int v[maxn], w[maxn];

//從第i個物品開始挑選總重量小於j的部分

int dfs(int i, int j)

但這種方案搜尋深度為n,最壞需要\(o(2^n)\)的時間複雜度,如何優化呢?

我們建立遞迴樹可以看到,dfs以(3,2)為引數呼叫了兩次。如果引數相同,則返回結果一定相同。我們可以很容易的想到用乙個陣列來記錄已經被算出來的部分,從而避免相同引數計算多次的情況。這裡我們用資料dp來記錄已經被求解的部分。**如下:

int n, w;

int v[maxn], w[maxn], dp[maxn][maxn];

//從第i個物品開始挑選總重量小於j的部分

int dfs(int i, int j)

int main()

這種稱為記憶化搜尋,接下來我們可以利用記憶化搜尋,來引入一定的遞推式,利用遞推式來求解問題的思路則為動態規劃(dp:dynamic programming)

動態規劃解決方案:我們設\(dp[i][j]\)表示為從前i個物品中挑選,放入最大容量為j的揹包中所能得到的最大價值。對於每個物品,只有拿與不拿兩種情況(即0與1),根據此思路可得如下遞推式:

\[dp[i][j] = \begin

dp[i-1][j] & j \le w[i] \quad 剩餘空間j無法放下物品i \\

max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]) & j \ge w[i] \quad 剩餘空間j可以放下物品i,則取不選與選的較大值

\end

\]根據規律可得下表:

牆裂建議親自動手推表!!!

**如下:

#include#includeusing namespace std;

typedef long long ll;

const int maxn = 2e3 + 5;

int n, w;

int v[maxn], w[maxn], dp[maxn][maxn];

int main()

滾動陣列優化:我們可以從遞推式中發現,dp[i]的所有數隻和dp[i-1]有關,和dp[i-2],dp[i-3]等沒有任何關係。我們可以想到:去掉陣列第1維,對於第n次dp陣列更新來說,在更新之前,dp[1..w]儲存的是第n-1次更新中已經更新完的資料。可得:

\[dp[j] = \begin

dp[j] & j \le w[i] \quad 剩餘空間j無法放下物品i \\

max(dp[j],dp[j-w[i]]+v[i]) & j \ge w[i] \quad 剩餘空間j可以放下物品i,則取不選與選的較大值

\end

\]化簡得:

\[dp[j] = max(dp[j],dp[j-w[i]]+v[i]) \quad j \ge w[i] \quad 剩餘空間j可以放下物品i,則取不選與選的較大值

\]但是我們需要注意,j的遍歷需要逆序進行!。原因是:如果正序進行,第n次dp陣列更新會覆蓋掉第n-1次dp陣列更新,例如遍歷完dp[3]時,此時的dp[3]若被更新,則是選擇了第n號物品,但是後續更新需要的是第n-1輪更新所得的dp陣列,違背了第n輪更新只需要第n-1輪更新的原則。可得如下**:

#include#includeusing namespace std;

typedef long long ll;

const int maxn = 2e3 + 5;

int n, w;

int v[maxn], w[maxn], dp[maxn];

int main()

動態規劃入門

1 用 dp 做的題大多數返回值是int boolean,求max min,不能打亂原來輸入順序。2 動態規劃有兩個重要定義,乙個叫 optimal substructure 另乙個叫 overlap subproblem 各種排序 tree 類問題中,都會用到 divide conquer 的思想...

動態規劃入門

大家可以看看這篇文章dp,哪個更容易理解就看哪個!一 動態規劃的定義 動態規劃程式設計是一種針對於解決最優化問題的一種途徑 一種方法,而不是一種特殊演算法,也就是說它沒有固定的模板。在動態規劃中,每走一步都要看看能不能最優,而且動態規劃最擅長的就是多階段問題!二 動態規劃的基本概和基本模型構成 1....

動態規劃入門

學動態規劃自然要從數字三角形開始起步,那麼我們就先從數字三角形開始。數字三角形題目 有乙個由非負整數組成的三角形,第一行只有乙個數,除了最下行之外的每個數的左下方和右下方各有乙個數,如下圖所示 3 24 10 1 4 3 2 20 從第一行的數開始,每次可以往下或往右下走一格,直到走到最下行,把沿途...