题目链接https://www.luogu.com.cn/problem/P1896#submit
AC代码
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int N=11;
const int K=1<<N;
typedef long long ll;
ll dp[N+1][102][K];
int sum[K];
vector<int> ana[K];
vector<int> state;
int n,k;
bool check(int s)
{
for(int i=0; i<n;i++)
{
if( (s>>i) & 1 == 1 && (s>>(i+1)) & 1 == 1)
return false;
}
return true;
}
int getsum(int s)
{
int sum=0;
for(int i=0;i< n;i++)
{
if((s>>i) & 1)
sum++;
}
return sum;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i< 1<<n;i++)
{
if(check(i))
state.push_back(i);
}//预处理 合法的状态(相邻不能有国王)
for(int i=0;i<state.size();i++)
for(int j=0;j<state.size();j++)
{
if((state[i]&state[j])==0 && check(state[j]|state[i]))
{
ana[state[i]].push_back(state[j]);
}
}//预处理各种状态下上一层可以合法的状态
for(int i=0;i< 1<<n;i++)
{
sum[i]=getsum(i);
}
dp[0][0][0]=1;
for(int i=1;i<=n+1;i++)
{
for(int p=0;p<=k;p++)
for(int j=0;j< state.size();j++)
{
if( p-sum[state[j]]>=0)
for(int z=0;z<ana[state[j]].size();z++)
{
dp[i][p][state[j]]+=dp[i-1][p-sum[state[j]]][ana[state[j]][z]];
}
}
}//DP
printf("%lld",dp[n+1][k][0]);
return 0;
}