狀态壓縮DP
預備知識:位運算!
位運算講稿 byMatrix67
注意:位運算的優先級非常低,用的時候一定要注意多加括号!
1.棋盤模型:給一個棋盤,問滿足要求的棋子放置方案數或最多放置數
1.sgu220TODO:littlebishop :攻擊範圍:對角線的4個點,SCR
2.sgu221TODO:bigBishop: 棋盤多項式
3.sgu222:n*n的棋盤,放k個車,使他們不能互相攻擊,問有多少種放法。
定義狀态S表示每列的放置情況,S為n位的二進制數,第i位為1表示第i列放棋子,為0表示不放棋子。
F[i][S]:前i行,列的狀态為S的方案數
F[i][S]=Sum(F[i-1][S],F[i-1][S-2^j])/每行至多放一個,目前行放置在第j個。
ans=sum(F[n][s]), 其中S中有k個1
複雜度O(N^2*2^N)
補充:本題有組合數學方法,C(N,K)*A(N,K)但不是講這題的目的。。。
4.sgu 223 n*n的棋盤,放k個國王,使他們不能互相攻擊,問有多少種放法。(國王攻擊範圍為他周圍的8個點)
這題因為不滿足每行隻放一個的條件,是以不能像上一題那樣解決。而且求解目前行,和上一行的狀态有關,是以狀态轉移的時候需要上行的狀态。
F[i][S][j]:前i行放j個國王,第i行狀态為S的方案數。
F[i][S][j]=sum(F[i-1][S'][j-Count(S)])S和S‘不沖突,Count(S)表示S中1的個數。
ans=Sum(F[i][S][K])
複雜度分析
狀态數:N*2^N*K(N^2)=N^3*2^N,轉移代價2^N
時間優化(減少狀态數):
每行的狀态S不必要從0到2^N-1枚舉,因為有些狀态行内就沖突了!
補充:格子數為m的一行放棋子,相鄰兩個棋子中間的空格數不少于d的狀态數:
Num=C(m,0)+C(m,1)+C(m-d,2)+C(m-2d,3)+......
可以dfs預處理出所有可行的狀态,把可行的狀态儲存起來,本題的可行狀态數大約減少為200個。總複雜度約為4*10^7
空間優化:滾動數組!
如何判斷S和S‘沖突。
(S<<1)&S'==0,S&S’==0,(S>>1)& S' ==0
5.POJ3254 求方案數,類似上題
6.POJ1185求最大放的個數
7.hdu4539TODO炮兵陣地:曼哈頓距離版
2.鋪磚/覆寫模型:
1.poj24111*2多米諾骨牌覆寫n*m的棋盤方案數。
公式(生成函數):mul(1-m/2)mul(1-n/2)[4cos^2(iPi/(m+1)+4cos^2(jPi/(n+1)) ]
狀态壓縮
Reference
1.位運算講稿by Matrix67
2.《狀态壓縮》——周偉