棋子 狀態壓縮dp

2021-06-19 07:40:12 字數 1301 閱讀 3318

題目描述:在乙個n*n的棋盤上放棋子,每乙個棋子的上下左右都沒有棋子,也就是不相鄰,一共有多少種放法?(n <= 8)

sample_input

0

13

sample_output12

63

分析:首先,我們可以逐行來擺放這些棋子,這樣我們會發現,每一行的擺放狀態只和上一行有關,這樣我們可以採用遞推

的方式來解決。

假設f[i][j]為第i行的擺放狀態為j時的擺放總數(j表示所有滿足條件的單行狀態,如01001二進位制表示0表示不放,1表

示放),那麼第i+1行的值就可以根據第i行來求,即f[i+1][k]=∑f[i][j] (j&k==0表示這兩行不會產生衝突)

例如第i行擺放狀態為 00101,則第i+1行的狀態10010滿足條件.

最後我們得到狀態轉移方程

f[i][j]=∑f[i-1][k](k表示所有與j不衝突的狀態,f[0][0]=1;

#include #include #include using namespace std;

int s[1111]; /**記錄所有滿足條件的單行表示*/

long long f[11][1111];/**f[i][j]表示第i行為第j種狀態的擺放總數*/

int n,m; /**n表示棋盤大小,m表示滿足條件的狀態數*/

long long ans; /**記錄答案*/

bool ok(int x )/**判斷x是否滿足條件*/

return 1;

}int main()

{ int i,j,k;

while(~scanf("%d",&n))

{for(m=i=0;i<1<

狀態壓縮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行種植,最後一...

狀態壓縮DP

總結狀壓dp轉移的方法 若某個狀態下可以對下 1.按二進位制讀入資料 2.列舉所有方案,如果合理 一行中沒有兩兩相鄰的 就儲存 i i 1 3.因為每一層的狀態只受上一層影響,因此迴圈兩次所有合理方案,為每乙個方案找到一系列下一層合理方案 4.遍歷每一行,並遍歷每一行的所有合理方案,若與預處理不矛盾...