車 狀態壓縮

2021-10-23 12:02:20 字數 1970 閱讀 9444

time limit:1000ms memory limit:65536k

total submit:95 accepted:38

description

在n ∗n

(n≤20

)n*n(n≤20)

n∗n(n≤

20)的方格棋盤上放置n

nn個車(可以攻擊所在行、列),有些格仔不能放,求使它們不能互相攻擊的方案總數。

input

第一行為棋盤的大小n

nn第二行為障礙的數量m

mm第三行到第m+3

m+3m+

3為mm

m個障礙

output

總數sample input42

1 12 2

sample output

14解題思路

狀態壓縮遞推(states compressing recursion,scr)

我們一行一行放置。

取棋子的放置情況作為狀態,某一列如果已經放置棋子則為1

11,否則為0

00。這樣,乙個狀態就可以用乙個最多20

2020

位的二進位制數表示。

例如n =5

n=5n=

5,第1、3

、41、3、4

1、3、

4列已經放置,則這個狀態可以表示為01101

01101

0110

1(從右到左)。設f[s

]f[s]

f[s]

為達到狀態s

ss的方案數,則可以嘗試建立f

ff的遞推關係。

考慮n =5

,s=01101

n=5,s=01101

n=5,s=

0110

1,因為我們是一行一行放置的,所以當達到s

ss時已經放到了第三行。又因為一行能且僅能放置乙個車,所以我們知道狀態s

ss一定來自(沒障礙物的情況下):

1. 前兩行在第3、4列放置了棋子(不考慮順序,下同),第三行在第1列放置;

2. 前兩行在第1、4列放置了棋子,第三行在第3列放置;

3. 前兩行在第1、3列放置了棋子,第三行在第4列放置。

圖示:

在列舉s中的1的時候判斷一下是否有障礙物即可

**

#include

#include

#include

#include

#include

using namespace std;

const int maxn=

1<<

20;

int n,m,num,x,y;

long long vis[25]

,f[maxn]

;int main()

f[0]=

1;for(int i=

1;i<

1<<

(n);i++

)//列舉可能出現的狀態

printf

("%lld"

,f[(

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.遍歷每一行,並遍歷每一行的所有合理方案,若與預處理不矛盾...