问题 B: [SCOI2005]互不侵犯King
时间限制: 1 Sec 内存限制: 162 MB题目描述
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
输入
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
输出
方案数。
样例输入
3 2
样例输出
16
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#define V 105
#define INF 1115006
#define S 1<<10+1
typedef long long LL;
//#define LL long long
using namespace std;
int a[INF],n,m;
LL s[V],f[10][101][90],c[V],ff[1000];
int dp[V][S];
int check(int,int);
int main()
{
// freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
//freopen("cannon.in","r",stdin);freopen("cannon.out","w",stdout);
int num=0;
int x,y;
char tt;
scanf("%d%d",&n,&m);
int k,ss=0,g,h,t,r,e,w,q;
for(int i=0;i<(1<<n);i++)
{
k=i;
if(((k<<1)&i)||((k>>1)&i))
continue;
ss++;
while(k!=0)
{
c[ss]++;
k-=k&(-k);
}
if(c[ss]>m)
{
c[ss]=0;
ss--;
continue;
}
ff[ss]=i;
}
//for(int i=1;i<=ss;i++)
//f[1][i][c[i]]+=1;
f[0][1][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=ss;j++)
{
for(int p=1;p<=ss;p++)
if(!(ff[j]&ff[p])&&!((ff[j]<<1)&ff[p])&&!((ff[j]>>1)&ff[p])&&c[j]+c[p]<=m)
for(int r=c[j];r<=m;r++)
f[i][j][r]+=f[i-1][p][r-c[j]];
}
}
LL ans=0;
for(int j=1;j<=ss;j++)
{
ans+=f[n][j][m];
}
cout<<ans<<endl;
return 0;
}