题意:在 N×N的棋盘里面放 K 个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共 8个格子。
#include<bits/stdc++.h>
using namespace std;
long long state[2010],sum[2010];
long long dp[10][100][2000];//行数,国王数,状态
int n,k,num,tot,snow;
int main()
{
cin>>n>>k;
for(int s=0;s<(1<<n);s++)
{
tot=0;snow=s;
while(snow)
{
if(snow&1)tot++;//找出这个状态有多少个1
snow>>=1;
}
sum[s]=tot;//处理状态有多少个king
if((((s<<1)|(s>>1))&s)==0)state[++num]=s;//不重复则为有效的状态
}
for(int i=1;i<=num;i++)
if(sum[state[i]]<=k)dp[1][sum[state[i]]][state[i]]=1;//预处理第一行
for(int i=2;i<=n;i++)
{
for(int j=1;j<=num;j++)
{
int nows=state[j];
for(int l=1;l<=num;l++)
{
int pres=state[l];
if(((pres|(pres<<1)|(pres>>1))&nows)==0)
{
for(int q=0;q<=k;q++)
if(q-sum[nows]>=0)dp[i][q][nows]+=dp[i-1][q-sum[nows]][pres];
}
}
}
}
long long ans=0;
for(int i=1;i<=num;i++)ans+=dp[n][k][state[i]]; //枚举第n行所有可能的情况,统计答案
printf("%lld\n",ans);
return 0;
}