關於動態規劃的線性DPの一己之見

記錄關於DP的歷程,隨着刷題而更新。
個人向,僅自己回顧用,若是有講不清楚的地方歡迎回復私信交流。

一般情況下,動態規劃的解題步驟是:
第一步:根據原問題和子問題來確定狀態(dp數組表示什麼東西)
第二步:根據狀態確定狀態轉移方程(怎樣求解dp數組 遞推?dfs?)
第三步:確定要不要優化和編程實現方式 (單調隊列?線段樹?)

先學習簡單的線性DP,其實關於線性DP的話,不外乎這幾種。

1. LIS(最長上升子序列)

其實LIS的話,是dp入門必不可少的題目,正常時間算法時間複雜度 n^2,可用二分或樹狀數組優化達到 nlogn,用 dp[i] 維護 i 位置的最小值,最後dp數組的長度即最長上升子序列的長度,但是具體的過程和內容卻無法求。

len=1;
dp[1]=a[1];
for(int i=2;i<=n;i++){
	if(dp[len]<a[i]) dp[++len]=a[i];
	else{
		ll k=lower_bound(dp+1,dp+len+1,a[i])-dp;
		dp[k]=a[i];
	}
}

2. LCS(最長公共子序列)

特殊的,假設序列a和b是1-n的排列組合,那麼可以離散化a序列,那麼求出b的最長上升子序列就是a與b的最長公共子序列。
tip: 因爲最長公共子序列是按位向後比對的,所以a序列每個元素在b序列中的位置如果遞增,就說明b中的這個數在a中的這個數整體位置偏後,可以考慮納入LCS——那麼就可以轉變成nlogn求用來記錄新的位置的離散化後的LIS。

3. 揹包問題

揹包問題就是以01揹包爲基礎進行擴展的一系列問題。

當求最優/最大利益時,假設 M 爲物品組數,T 爲最大容量,a[i] 爲每一件物品的體積,b[i] 爲每一件物品的價值,c[i] 爲消耗的容量不大於i的情況下所獲得的最大收益,則有 :

// 1. 逆序 01 揹包
for(int i=1;i<=M;i++)
        for(int j=T;j>=a[i];j--)
            c[j]=max(c[j],c[j-a[i]]+b[i]);

//2. 正序 完全 揹包
 for(int i=1;i<=M;i++)
        for(int j=a[i];j<=T;j++)
            c[j]=max(c[j],c[j-a[i]]+b[i]);

而其他的情況多重揹包不過是多了一個把物品拆分/合併的過程,而分組揹包不過是多了一個決策過程,經過這些的猜想,不難得出揹包的dp模板:

  1. 第一層 for 枚舉物品的組數
  2. 第二層 for 枚舉物品的容量
  3. 第三層 for 進行決策

而當遇到求方案數時,也是可以由揹包得出經驗,不外乎個數有限與無限的區別,那麼其實就是01揹包/完全揹包:

// 1. 逆序 01 揹包
for(int i=1;i<=M;i++)
        for(int j=T;j>=a[i];j--)
            c[j]+=c[j-b[i]];

//2. 逆序 完全 揹包
 for(int i=1;i<=M;i++)
        for(int j=a[i];j<=T;j++)
           c[j]+=c[j-b[i]];

可以發現,不過是狀態轉移的方程改變了而已。

4. dirworth定理

求最長上升序列的長度等於求最長不上升序列的劃分個數。

5. 其他問題總結

  1. 迴文串:dp[i][j] 爲字符串 的第 i 個字符到第 j 個字符的最長迴文子序列長度。
    特殊的: dp[i][j]=dp[i+1][j1]+2dp[i][j]=dp[i+1][j−1]+2 ifs[i]==s[j]if s[i]==s[j]
    一般的: dp[i][j]=max(dp[i+1][j]dp[i][j1])dp[i][j]= max(dp[i+1][j],dp[i][j-1])

  2. 題目:多個串的匹配,考慮 dp[i][j]dp[i][j]爲s1的前i個字符與s2的前j個字符。

  3. 題目:n個箱子選前k小的價值和,例如 dp[i][k]dp[i][k] 爲前i個箱子的價值爲k的方案。

  4. 題目:對於挑選方案可以按照揹包思想,根據題目劃分爲01揹包或者完全揹包,再考慮是否是分組揹包(有決策層)。

  5. 題目:對於數列型題目,可以考慮類似於LIS或者LCS來思考,以dp[i]dp[i]表示以當前元素結尾的狀態值,若是元素範圍少,可考慮爲 dp[i][j]dp[i][j]a[i]a[i] 結尾且和爲jj 或者差爲 jj 等等狀態,把第二維作爲對於給出條件的一種枚舉。

以上,其他內容等遇到再補充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章