当前位置: 代码迷 >> 综合 >> [SCOI2005]互不侵犯King
  详细解决方案

[SCOI2005]互不侵犯King

热度:87   发布时间:2023-11-23 17:10:49.0

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