问题 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;
}