狀態壓縮DP 樹形D

2021-06-13 10:55:00 字數 2245 閱讀 5000

動態規劃的狀態有時候比較難,不容易表示出來,需要用一些編碼技術,把狀態壓縮的用簡單的方式表示出來。典型方式:當需要表示乙個集合有哪些元素時,往往利用2進製用乙個整數表示。

*:一般有個資料 n<16 或者 n<32 這個很可能就是狀態dp的標誌,因為我們要用乙個int的二進位制來表示這些狀態。要注意好這些資料規模的提示作用。

*:確定了為狀態dp,那麼第一步就是預處理,求出每行所有可能的狀態了,cnt記錄總的狀態數,stk記錄所有的可能狀態。以炮兵陣地為例:

int cnt, stk[max];

void findstk(int n)

return num;

}*:然後就是dp部分了,明確好狀態轉移方程。先特殊處理第1行,然後按狀態轉移方程求出剩下的值。

經典問題:tsp

乙個n個點的帶權的有向圖,求一條路徑,使得這條路經過每個點恰好一次,並且路徑上邊的權值和最小(或者最大)。或者求一條具有這樣性質的迴路,這是經典的tsp問題。

n <= 16 (重要條件,狀態壓縮的標誌)

如何表示乙個點集:

由於只有16個點,所以我們用乙個整數表示乙個點集:

例如:5 = 0000000000000101;(2進製表示)

它的第0位和第2位是1,就表示這個點集裡有2個點,分別是點0和點2。

31 = 0000000000011111; (2進製表示)

表示這個點集裡有5個點,分別是0,1,2,4,5;

所以乙個整數i就表示了乙個點集;整數i可以表示乙個點集,也可以表示是第i個點。

狀態表示:

dp[i][j]表示經過點集i中的點恰好一次,不經過其它的點,並且以j點為終點的路徑,權值和的最小值,如果這個狀態不存在,就是無窮大。

狀態轉移:

單點集:狀態存在dp[i][j] = 0;否則無窮大。非單點集:

1:狀態存在  dp[i][j] = min(dp[k][s] + w[s][j])

k表示i集合中去掉了j點的集合,s遍歷集合k中的點並且dp[k][s]狀態存在,點s到點j有邊存在,w[s][j]表示邊的權值。

2.:狀態不存在 dp[i][j]為無窮大。

最後的結果是: min( dp[( 1<

樹本身就是乙個遞迴的結構,所以在樹上進行動態規劃或者遞推是最合適不過的事情。

必要條件:子樹之間不可以相互干擾,如果本來是相互干擾的,那麼我們必須新增變數使得他們不相互干擾。

party at hali-bula

題目大意:n個人形成乙個關係樹,每個節點代表乙個人,節點的根表示這個人的唯一的直接上司,只有根沒有上司。要求選取一部分人出來,使得每2個人之間不能有直接的上下級的關係,求最多能選多少個人出來,並且求出獲得最大人數的選人方案是否唯一。

這是乙個經典的樹型動態規劃,人之間的關係形成樹型結構,簡單的染色統計是不正確的

dp部分:用dp[i][0]表示不選擇i點時,i點及其子樹能選出的最多人數,dp[i][1]表示選擇i點時,i點及其子樹的最多人數。

狀態轉移方程:

對於葉子節點: dp[k][0] = 0, dp[k][1] = 1

對於非葉子節點i: dp[i][0] = ∑max(dp[j][0], dp[j][1]) (j是i的兒子)

dp[i][1] = 1 + ∑dp[j][0] (j是i的兒子) 

最多人數即為:max(dp[0][0], dp[0][1])

如何判斷最優解是否唯一?

新加乙個狀態dup[i][j],表示相應的dp[i][j]是否是唯一方案。

對於葉子結點:dup[k][0] = dup[k][1] = 1.

對於非葉子結點:

1:i的任一兒子j,若(dp[j][0] > dp[j][1] 且 dup[j][0] == 0) 或 (dp[j][0] < dp[j][1] 且 dup[j][1] == 0) 或 (dp[j][0] == dp[j][1]),則dup[i][0] = 0

2:i的任一兒子j有dup[j][0] = 0, 則dup[i][1] = 0

strategic game

典型的樹型動態規劃:

dproot[ i ]表示以i為根的子樹,在i上放置乙個士兵,看守住整個子樹需要多少士兵。

all[ i ]表示看守住整個以i為根的子樹需要多少士兵。

狀態轉移方程:

葉子節點:dproot[k] =1; all[k] = 0;

非葉子節點: dproot[i] = 1 + ∑all[j](j是i的兒子);

all[i] = min( dproot[i], ∑dproot[j](j是i的兒子) );

狀態壓縮dp與樹形dp

狀態壓縮動態規劃 動態規劃的狀態有時候比較難,不容易表示出來,需要用一些編碼技術,把狀態壓縮的用簡單的方式表示出來。典型方式 當需要表示乙個集合有哪些元素時,往往利用2進製用乙個整數表示。一般有個資料 n 16 或者 n 32 這個很可能就是狀態dp的標誌,因為我們要用乙個int的二進位制來表示這些...

狀態壓縮DP

首先,我們以一道狀壓經典題tsp來引入。tsp問題 一張圖上有n個點,給定相應的鄰接矩陣,需要求出從0號節點出發,經過且只經過每個頂點一次,最後仍回到0號節點的最小邊權。思路 假設現在已訪問過的頂點集合 起點0當作還未訪問過的頂點 為s,當前所在頂點為v,用dp s v 表示從v出發訪問剩餘的所有頂...

狀態壓縮DP

theme 給定乙個n m的玉公尺田,1 n,m 12。值為0表示不能在該塊種草,為1表示可以。現在要在其上中若干草地,要求任意草地間不相鄰 沒有公共邊 問不考慮草地個數的情況下,有多少種種植的方案?solution 用dp。又範圍很小,所以考慮狀態壓縮dp,另dp i j 表示從前i行種植,最後一...