还是DP+状态压缩
貌似我写的只有DP了吧。。
提交传送门
这题状态压缩变态,枚举的是有多少个King。。。很不一样。
SO。又是做了很久,还有2进制压缩。Dp方程还是很难。。
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
>只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
3 2
Sample Output
16
大家还是早点Ak吧
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
struct node{
LL i,c;
}v[(1<<10)+10];
LL vn,f[10][110][(1<<10)+10],d[110];
int n,m;
int main(){
d[0]=1;for(int i=1;i<=20;i++)d[i]=d[i-1]*2;
scanf("%d%d",&n,&m);
memset(f,0,sizeof(f));
int mmax=(1<<n)-1;
for(int i=0;i<=mmax;i++){
if((i&(i<<1))==0){
v[++vn].i=i;v[vn].c=0;
int t=i,p=0;
while(t!=0){
if((t&d[p])==d[p]){
v[vn].c++;t-=d[p];
}
p++;
}
f[1][v[vn].c][i]=1;
}
}
for(int x=2;x<=n;x++){
for(int p=1;p<=vn;p++){
for(int q=1;q<=vn;q++){
if((v[p].i&v[q].i)==0){
if(((v[q].i>>1)&v[p].i)==0&&((v[q].i<<1)&v[p].i)==0&&v[p].c+v[q].c<=m){
for(int i=v[q].c;i<=m-v[p].c;i++){
f[x][v[p].c+i][v[p].i]+=f[x-1][i][v[q].i];
}
}
}
}
}
}
LL ans=0;
for(int x=1;x<=vn;x++)ans+=f[n][m][v[x].i];
printf("%lld\n",ans);
return 0;
}