有關狀態壓縮dp

其實狀態壓縮dp就是一個普通的dp加一個對集合的操作,只是把這個集合“壓縮”一下,所以這裏簡單說一下怎樣表示一個集合以及對它進行操作。

首先,我們爲什麼要狀態壓縮?因爲有時我們需要用東西表示一個集合。比如經典的TSP問題,它需要用到一個集合S來表示已經遍歷的點(這些點用不同的數字表示),那麼如何來表示集合S呢?這裏我們可以利用二進制的方法:將集合中的元素對應二進制中的1,其它的爲0,這樣就產生了一個二進制數,這個二進制數對應着一個十進制數,所以這個十進制數就可表示這個集合。由於不同的集合對應着不同的二進制,也就有不同的十進制數,所以不用擔心一個十進制數會對應着不同的集合。比如:集合{1,3,4}可表示爲11010,也就是26。集合{0,3,4,8}可表示爲100011001,也就是21。從左往右、從0可是標號。

然後說一下位運算。位運算是對於二進制的運算,兩個十進制數間進行爲運算時它會自動將兩個數轉化爲二進制數進行運算。爲運算有"&"(與運算)、"|"(或運算)、"^"(與或運算)、“~”(取反)。這些位運算的運算法則我就不說了,自己不知道可以百度下。我說下他們對集合的意義:

& :取兩個集合的交

|  : 取兩個集合的並

^ : 取兩個集合的對稱差

~ : 對一個集合取反(也就是集合s與集合~s的交集爲空)

還有"<<"(左移)、">>"(右移)也是重要的運算符。


假設集合S有n個元素{0,1,...,n-1},則一些集合運算可以對應地寫成如下方式。


空集∅:.......................................................................0

只含有第i個元素的集合{i}: ...........................................1<<i      (此時在二進制中只有第i個位置時1,其餘爲0)

含有全部n個元素的集合{0,1,...,n-1}: ...........................(1<<n)-1   (此時二進制中位置0,1,...n-1上都是1)

判斷第i個元素是否屬於集合S:...................................if(S>>i&1)    (就是判斷第i個位置是否爲1,也可以寫成if(S&(1<<i)),這裏">>"運算優先級比"&"高)

向集合中加入第i個元素S∪{i}:...................................S|1<<i        (保證集合S中的第i位一定是1,"<<“運算優先級比"|"高)

向集合中去除第i個元素S\{i}:......................................S&~(1<<i)   (保證集合S中的第i位一定是0)

集合S和T的並集S∪T:...............................................S|T

集合S和T的交集S∩T:................................................S&T


x&(-x) : 將x最低位的1獨立出來後的值。

x&(x-1) : 將x的最低位的1變爲0後的值。

x|(x+1) : 將x的最低位的0變爲1後的值。


相關題目:

① 炮兵陣地(我的入門題,需要dp知識):http://poj.org/problem?id=1185

② 搜索+狀態壓縮 :http://acm.hdu.edu.cn/showproblem.php?pid=5025

③ TSP問題 :http://codeforces.com/problemset/problem/580/D

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