1. 程式人生 > >ACM 動態規劃(簡稱dp) 分類

ACM 動態規劃(簡稱dp) 分類

動態規劃一直是ACM競賽中的重點,同時又是難點,因為該演算法時間效率高,程式碼量少,多元性強,主要考察思維能力、建模抽象能力、靈活度。

******************************************************************************************

動態規劃英語:Dynamic programming,DP)是一種在數學電腦科學經濟學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。 動態規劃常常適用於有重疊子問題最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。

動態規劃背後的基本思想非常簡單。大致上,若要解一個給定問題,我們需要解其不同部分(即子問題),再合併子問題的解以得出原問題的解。 通常許多子問題非常相似,為此動態規劃法試圖僅僅解決每個子問題一次,從而減少計算量: 一旦某個給定子問題的解已經算出,則將其

記憶化儲存,以便下次需要同一個子問題解之時直接查表。 這種做法在重複子問題的數目關於輸入的規模呈指數增長時特別有用。

動態規劃問題滿足三大重要性質

最優子結構性質:如果問題的最優解所包含的子問題的解也是最優的,我們就稱該問題具有最優子結構性質(即滿足最優化原理)。最優子結構性質為動態規劃演算法解決問題提供了重要線索。

子問題重疊性質:子問題重疊性質是指在用遞迴演算法自頂向下對問題進行求解時,每次產生的子問題並不總是新問題,有些子問題會被重複計算多次。動態規劃演算法正是利用了這種子問題的重疊性質,對每一個子問題只計算一次,然後將其計算結果儲存在一個表格中,當再次需要計算已經計算過的子問題時,只是在表格中簡單地檢視一下結果,從而獲得較高的效率。

無後效性:將各階段按照一定的次序排列好之後,對於某個給定的階段狀態,它以前各階段的狀態無法直接影響它未來的決策,而只能通過當前的這個狀態。換句話說,每個狀態都是過去歷史的一個完整總結。這就是無後向性,又稱為無後效性。

********************************************************************************************

動態規劃分類有很多劃分方法,網上有很多是按照狀態來分,分為一維、二維、區間、樹形等等。我覺得還是按功能即解決的問題的型別以及難易程度來分比較好,下面按照我自己的理解和歸納,把動態規劃的分類如下:

一、簡單基礎dp

這類dp主要是一些狀態比較容易表示,轉移方程比較好想,問題比較基本常見的。主要包括遞推、揹包、LIS(最長遞增序列),LCS(最長公共子序列),下面針對這幾種型別,推薦一下比較好的學習資料和題目。

1、遞推:

遞推一般形式比較單一,從前往後,分類列舉就行。

簡單:

推薦:

2、揹包

主要有0-1揹包、完全揹包、分組揹包、多重揹包。

簡單:

推薦:

3、LIS

最長遞增子序列,樸素的是o(n^2)演算法,二分下可以寫成o(nlgn):維護一個當前最優的遞增序列——找到恰好大於它更新

簡單:

推薦:

4、LCS

最長公共子序列,通常o(n^2)的演算法

二、區間dp

區間dp,一般是列舉區間,把區間分成左右兩部分,然後求出左右區間再合併。

三、樹形dp

樹形dp是建立在樹這種資料結構上的dp,一般狀態比較好想,通過dfs維護從根到葉子或從葉子到根的狀態轉移。

四、數位dp

數位dp,主要用來解決統計滿足某類特殊關係或有某些特點的區間內的數的個數,它是按位來進行計數統計的,可以儲存子狀態,速度較快。數位dp做多了後,套路基本上都差不多,關鍵把要儲存的狀態給抽象出來,儲存下來。

五、概率(期望) dp

推薦論文:

一般來說概率正著推,期望逆著推。有環的一般要用到高斯消元解方程。期望可以分解成多個子期望的加權和,權為子期望發生的概率,即 E(aA+bB+...) = aE(A) + bE(B) +... 

六、狀態壓縮dp

這類問題有TSP插頭dp等。

七、資料結構優化的dp

有時儘管狀態找好了,轉移方程的想好了,但時間複雜度比較大,需要用資料結構進行優化。常見的優化有二進位制優化、單調佇列優化、斜率優化、四邊形不等式優化等。

1、二進位制優化

主要是優化揹包問題,揹包九講裡面有介紹,比較簡單,這裡只附上幾道題目。

2、單調佇列優化

3、斜率優化

4、四邊形不等式優化