time limit: 10 sec
memory limit: 162 mb
submit: 4064
solved: 2354 [
submit][
status][
discuss]
在n×n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上
左下右上右下八個方向上附近的各乙個格仔,共8個格仔。
只有一行,包含兩個數n,k ( 1 <=n <=9, 0 <= k <= n * n)
方案數。
3 216
一道狀壓dp。
狀壓dp就是可以解決一些狀態不易表達的問題。本題中將放國王與不放設定為0和1即可把每一行的狀態變為乙個01串,再對應二進位制轉十進位制即可表達狀態。設f[i][j][s]表示第i行共用了k個國王,且第i行擺法的二進位制轉十進位制為s的方案總數。考慮兩個問題,1.如何轉移?列舉前一行的狀態 2.如何判斷狀態是否合法?利用位運算的&字元,國王可以攻擊八聯通方向,而我們更新時只需要關注左上,正上,右上,左,右五個位置,若能攻擊到,則水平方向相鄰兩個位置必有國王,所以我們只需要把兩個狀態&一下,若結果為0,證明兩行不存在國王在國王的正上方,再將某乙個左移一位,&一下,再右移一位,&一下,即可保證斜上方也不存在國王可以攻擊。
細節有很多地方,需要保證列舉的狀態合法,前一行的狀態合法,故要有很多&操作。
#include#include#include#include#include#include#include#includeusing namespace std;
const int maxn=11;
const int maxm=520;
long long f[maxn][maxn*maxn][maxm];
int main()
x/=2;
}f[1][tot][i]=1;
} }for (int i=2;i<=n;i++)
if ((j & p)!=0)
if ((j&(p<<1))!=0)
if ((j&(j>>1))!=0)
if ((p&(p>>1))==0)
x/=2;
}if (tot1+q>k)
f[i][tot1+q][j]+=f[i-1][q][p];}}
}} }
long long ans=0;
for (int i=0;i<=(1<
BZOJ 1087, 互不侵犯
傳送門 給定一張大小為n n的棋盤,要求放置k個棋子,其中,棋子上下左右以及左上 左下 右上和右下八個位置不得有其它棋子存在。求合法方案數。動態規劃。狀態數很多,可以先預處理出一行的合法放置方案,再處理出上一行放置的情況下,下一行哪些方案是可行的,於是一行一行轉移即可。運用位運算優化預處理,後來四重...
BZOJ 1087( ) 互不侵犯
1087 scoi2005 互不侵犯king time limit 10 sec memory limit 162 mb submit 5333 solved 3101 submit status discuss description 在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方...
BZOJ 1087 互不侵犯King
1087 scoi2005 互不侵犯king time limit 10 sec memory limit 162 mb description 在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上 左下右上右下八個方向上附近的各乙個格仔,共8個格仔。i...