传送门biu~
把一行中每个点是否有国王压缩成一个状态。二进制的每一位代表这个点是否有国王。例如:状态
10010
表示第一列和第四列有国王,第二列第三列第五列没有国王。
fi,j,now
代表前
i
行一共有
在判断能否互相攻击时,
(now<<1)&now=0
即为本行之间无法互相攻击,
now&pre=0
且
(now<<1)&pre=0
且
(now>>1)&pre=0
即为两行之间无法互相攻击。
#include<bits/stdc++.h>
using namespace std;
int n,k,num[512];
long long ans,f[10][82][512];
bool flag[512];
inline void init(){
for(int i=0;i<(1<<n);++i){
if(!(i&(i<<1))){
flag[i]=true;
int t=i;
while(t){
num[i]+=(t&1);
t>>=1;
}
f[1][num[i]][i]=1;
}
}
}
int main(){
scanf("%d%d",&n,&k);
init();
for(int i=2;i<=n;++i){
for(int j=0;j<=k;++j){
for(int now=0;now<(1<<n);++now){
if(!flag[now] || num[now]>j) continue;
for(int pre=0;pre<(1<<n);++pre){
if(!flag[pre] || (now&pre) || ((now<<1)&pre) || ((now>>1)&pre)) continue;
f[i][j][now]+=f[i-1][j-num[now]][pre];
}
}
}
}
for(int i=0;i<(1<<n);++i) ans+=f[n][k][i];
printf("%lld",ans);
return 0;
}