題意:在n×n
n×nn×
n的棋盤裡面放k
kk個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8
88個格仔。
考慮如何狀壓,對於每一行,我們用乙個長度為n
nn的二進位制串表示每一行的狀態,比如1010
1010
1010
表示第乙個,第三個位置上有國王,而1010
1010
1010
對應的十進位制數為10
1010
,我們將每一行的狀態都用二進位制表示然後狀壓成乙個十進位制數。一共有2n−
12^-1
2n−1
種狀態,因為最多的就是一行全為1
11的情況。
接下來設計狀態:dp[
i][j
][k]
dp[i][j][k]
dp[i][
j][k
]表示第i
ii行的狀態為j
jj(j
jj即為狀壓後的十進位制數),前i
ii行一共使用了k
kk個國王。這裡定義num
[i
]num[i]
num[i]
表示一行狀態為i
ii時的國王個數,k
kk為當前這一行的狀態,j
jj為上一行的狀態,q
qq為到前一行總共放的國王個數。所以:dp[
i][k
][q+
num[
k]]+
=dp[
i−1]
[j][
q]
;dp[i][k][q+num[k]]+=dp[i-1][j][q];
dp[i][
k][q
+num
[k]]
+=dp
[i−1
][j]
[q];
首先我們先預處理出對於一行內哪些狀態是合法的,如果狀態i
ii合法即記boo
k[i]
=1
book[i]=1
book[i
]=1,對於每一種合法狀態,我們處理出合法這種狀態需要的國王個數num
[i
]num[i]
num[i]
。對於同一行,乙個國王不能有左右相鄰的國王,所以對於狀態i
ii,我們讓i
ii&(
i>
>1)
,i
(i>>1),i
(i>
>1)
,i&(
i<
<1)
(i<<1)
(i<
<1)
如果二者都為0
00,即為合法。對於乙個合法狀態i
ii,我們對它進行二進位制分解,求出其中有多少個1
11,即為num
[i
]num[i]
num[i]
,然後設出初始狀態f[1
][x]
[num
[x]]
=1
f[1][x][num[x]]=1
f[1][x
][nu
m[x]
]=1。
for
(ll i=
0;i<(1
<;++i)
if(book[i]
) dp[1]
[i][num[i]]=
1;}
接下來我們分別列舉每一行i
ii,前一行的狀態j
jj,如果前一行的狀態合法,就繼續列舉當前行的所有狀態k
kk,對於當前行的所有狀態,我們首先判斷它是否合法,然後讓前一行的狀態分別&k,(
k<
<1)
,(
k>
>1)
k,(k<<1),(k>>1)
k,(k
<
<1)
,(k>
>1)
,如果均為0
00即視為合法,列舉到前一行總共放的國王個數根據方程進行累加轉移。
最後列舉最後一行的所有狀態累加一下答案即可。
#include
#define ll long long
using namespace std;
ll dp[20]
[1000][
100]
,num[
1000];
bool book[
1000];
ll n,king,ans;
intmain()
if(book[i]
) dp[1]
[i][num[i]]=
1;}for
(ll i=
2;i<=n;
++i)
for(ll j=
0;j<(1
<;++j)
if(book[j]
)for
(ll k=
0;k<(1
<;++k)
if(book[k]&&!
(k&j)&&!
((k<<1)
&j)&&!(
(k>>1)
&j))
for(ll q=num[j]
;q+num[k]
<=king;
++q)
dp[i]
[k][q+num[k]]+
=dp[i-1]
[j][q]
;for
(ll i=
0;i<(1
<;++i)
ans+
=dp[n]
[i][king]
; cout
}
SCOI2005 互不侵犯(狀壓DP)
題意 給定乙個n n的棋盤,放置k個國王,使他們互相攻擊不到對方,共有多少種方案。國王可以攻擊上下左右,左上左下,右上右下附近的一格,共8格。資料範圍 1 n 9,0 k n n.因為n的範圍很小,而且每一行對應的乙個方案可以用乙個二進位制數表示,所以容易想到用狀壓dp。又因題目有限制要用多少個國王...
SCOI2005 互不侵犯(狀壓DP)
在 n n 的棋盤裡面放 k 個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔。一行 n,k 方案數狀態壓縮dp基礎 狀壓和二進位制有著不可割捨的聯絡 一幫情況下,我 習慣把狀態抽象成一維 並且用二進位制表示,然後再去想怎...
SCOI2005 互不侵犯 (狀壓DP)
題目鏈結 在 n times n 的棋盤裡面放 k 個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共 8 個格仔。1 le n le 9,0 le k le n n f i,j,l 來表示前 i 行,當前狀態為 j 且已經放置 l...