今天也是為了cc,努力奮鬥的一天ヾ(≧▽≦*)o前面幾節介紹了動態規劃的相關概念,並求解了一些經典的動態規劃模型。但是在實際碰到新的問題時,初學者總是容易陷入頭腦一片空白、完全無法設計狀態的情況,這是正常現象,因為動態規劃本身就需要經驗的積累和大量做題才能有較大的提公升。不過從上面的經典模型中還是能總結出一些規律性的東西,由於動態規劃的重點在於狀態上,所以這些規律也是用於狀態的定義上的。
先把前面介紹過的動態規劃模型列舉如下:
(1)最大連續子串行和
dp[i]
:以a[i]
作為結尾的連續序列的最大和。
(2)最長不下降子串行(lis)
dp[i]
:以a[i]
作為結尾的最長不下降序列長度。
(3)最長公共子串行(lcs)
dp[i][j]
:字串a的i
號位和字串b的j
號位之前的lcs長度
(4)最長回文子串
dp[i][j]
:s[i]
至s[j]
所表示的子串是否為回文子串
(5)數塔dp
dp[i][j]
:從第i
行第j
個數字出發的到達最底層的所有路徑上所能得到的最大和。
(6)dag最長路
dp[i]
:從i
號頂點出發能獲得的最長路徑長度
(7)01揹包
dp[i][v]
:前i
件物品裝入容量為v
的揹包中能獲得的最大價值。
(8)完全揹包
dp[i][v]
:前i
件物品裝入容量為v
的揹包中能獲得的最大價值。
先看(1)~(4),這4個都是關於序列或字串的問題(特別說明:一般來說,「子串行」可以不連續,「子串」必須連續)。可以注意到:
這就給我們一些啟發:
當題目與序列或字串(即為a)有關時,可以考慮把狀態設計成下面兩種形式,然後根據端點特點去考慮狀態轉移方程。
(1)令dp[i]表示以a[i]結尾(或開頭)的***。
(2)令dp[i][j]表示a[i]至a[j]區間的***。
其中***均為原問題的描述。
接著來看(5)~(8),可以發現它們的狀態設計都包含了某種「方向」的意思。如:
這又說明了一類動態規劃問題的狀態設計方法:
分析題目中的狀態需要幾維來表示,然後對其中的每一維採取下面的某乙個表述:
恰好為i。
前i。(揹包問題中用到)
在每一維的含義設定完畢之後,dp陣列的含義就可以設定成「令dp陣列表示恰好為i(或前i)、恰好為j(或前j)…的***」,其中***為原問題的描述。接下來就可以通過端點的特點去考慮狀態轉移方程。
我們說動態規劃要設計狀態陣列,那麼狀態陣列的維度通常有哪些東西呢?如下:
乙個已有陣列變數的陣列下標範圍(如lis,lcs等等);
乙個已有變數的取值範圍(如揹包問題中的v)
最後需要說明的是,在大多數的情況下,都可以把動態規劃可解的問題看作乙個有向無環圖(dag),圖中的結點就是狀態,邊就是狀態轉移方向,求解問題的順序就是按照dag的拓撲序列進行求解的。從這個角度可以輔助理解動態規劃,建議讀者能結合講解過的幾個動態規劃模型予以理解。
其實,我們知道動態規劃可以使用遞迴來實現,visualgo**提供了常見動態規劃問題的視覺化遞迴實現,在視覺化中,我們可以清楚看到動態規劃可解的問題可看作乙個有向無環圖(dag),即遞迴樹的形式。
C 知識點 動態規劃04
今天這篇博文介紹一下動態規劃。先看下邊的經典問題 最長增長子串 例如 3,2,6,4,5,1 的最長增長子串是 2,4,5.先看一下實現 include include using namespace std void prt vector d 不多,這個問題如果採用暴力方法,就是考慮所有的組合,這...
知識點總結
1,迴圈中的中斷 continue 跳出此次迴圈,繼續for迴圈 break 跳出當前for迴圈 return 跳出當前方法 2,字串的操作 componentseparatedbystring stringbyreplacingoccurencesofstring withstring iskin...
知識點總結
oncreate onstrat onresume onpause onstop onrestart ondestroy standard 啟動activity都會產生乙個新的activity 預設模式 singletop 啟動activity允許多個,但不允許重疊 singletask 只允許有乙...