SGU 131 狀壓壓縮 dp

2021-07-11 05:12:37 字數 1754 閱讀 4304

// 題意:乙個n*m的矩陣,求用i型(1 * 2)和l型的兩種方塊進行填滿有多少種方法

// 方法:這題和poj2411有點類似 做過方塊填充的應該都認得出來要用狀壓

// 但是要比poj2411複雜 思路也是類似 不過因為要考慮l型 情況也複雜的多

// 語文有點不太好 可能有點說不清楚

// 利用兩個引數 b1 表示前面的放置方式對now(當前行狀態)的當前列的影響,b2 表示對pre(上一行狀態)的當前列的影響

// 有影響為1 沒影響為0 其實可以這麼理解 如果為1就代表有方塊從左邊凸出來會占用當前列 為0就代表沒有凸出來

// 這裡我提出一些自己遇到的問題

// 首先列舉當前狀態和上一狀態要分成兩種情況考慮

// 不僅要考慮b1,b2 還要考慮從下往下凸出來的這種情況,就是上一行的上一行有方塊凸下來占用上一行 說起來有點繞

// 舉個例子 如果當前 b1 == 0 && b2 == 0

// 那麼這一列我們可以這麼放

// 1 1 1 1 1 1

// 或者 或者 或者 (這四種是上一行的上一行沒有從上往下凸出來的方塊的放置方法)

// 1 1 1 1 1

// 1

// 或者 或者 不放 (這三種是上一行的上一行有從上往下凸出來的方塊的放置方法)

// 1 1 1 1

// 上面總共7種 上面的每種都滿足把上一行的當前列填滿了 只不過是分為是由左邊凸出來的 和 上面凸出來的

// 填滿我起初也有疑問為什麼下面的這三種放置也可以

// 語文果然不太好 看下面幾張圖一定有用

// 一 二 三 四 五 六

// 1 1 1 1 1 1 1

// 1 1 1 1 1 1 1 1 1

void dfs(int line, int k, int now, int pre, int b1, int b2)

if(!b1 && !b2)

else if( b1 && !b2)

else if(!b1 && b2)

else

}int main()

{ memset(ans, 0, sizeof ans);

memset(dp, 0, sizeof dp);

while(cin>>n>>m)

{if(ans[n][m]){

cout<

SGU 131 狀態壓縮dp

include include include include include include include include include include include include includeusing namespace std ifdef win32 define i64 int6...

SGU 223 國王 狀壓DP

在 n n n n 的棋盤上放 k k k 個國王,國王可攻擊相鄰的 8 8 8 個格仔,求使它們無法互相攻擊的方案總數。n n 狀壓dp是一種比較暴力的dp。n n 首先dp i j k 表示前i行放置k個國王,且當前行狀態是j的方案數。n n 轉移方程 dp i j k dp i 1 m k s...

狀壓dp(總結)狀態壓縮

狀壓這個和二進位制分不開關係 所以,對於二進位制的熟悉是必不可少的技能 與操作,1不變,0變0 或操作,0不變,1變1 異或操作,0不變,1取反 取反操作,把每乙個二進位制位0變1,1變0 還有一些複雜操作可以根據這些去理解 狀態壓縮 所謂狀態壓縮就是把dp的每一次轉移時的狀態用二進位制來表示 或者...