找不出来问题了 QWQ
#include<bits/stdc++.h>
using namespace std;
//1.判断一个数字x二进制下第i位是不是等于1。(最低第1位)
//方法:if(((1<<(i-1))&x)>0) 将1左移i-1位,相当于制造了一个只有第i位 上是1,其他位上都是0的二进制数。然后与x做与运算,如果结果>0, 说明x第i位上是1,反之则是0。
//2.将一个数字x二进制下第i位更改成1。
//方法:x=x|(1<<(i-1)) 证明方法与1类似。
//3.将一个数字x二进制下第i位更改成0。
//方法:x=x&~(1<<(i-1))
//4.把一个数字二进制下最靠右的第一个1去掉。
//方法:x=x&(x-1)
const int maxn=155;
long long f[11][maxn][maxn],ans;
int a[maxn],s[maxn];
int N,K,S;
void pre(){//预处理 状压
S=0;
ans=0;
int cnt;
memset(f,0,sizeof(f));
for(int i=0;i<(1<<N);i++){//枚举每行状态
if(i&(i<<1)) continue;//检查当前行状态是否冲突
cnt=0;
for(int j=0;j<N;j++)
if(i&(1<<j)) cnt++;
s[++S]=0; //可用状态i,总计可用状态S状压
a[S]=cnt; //每种状态放置国王的数量
}
}
void dp(){//dp 核心部分
f[0][1][0]=1; //初始化, 第0行放0个国王的方案为1
for(int i=1;i<=N;i++)
for(int j=1;j<=S;j++)
for(int k=0;k<=K;k++)
if(k>=a[j])
for(int t=1;t<=S;t++)
if(!(s[t]&s[j]) && !(s[t]&(s[j]<<1)) && !(s[t]&(s[j]>>1))) //无冲突
f[i][j][k]+=f[i-1][t][k-a[j]];
for(int i=1;i<=S;i++) ans+=f[N][i][K]; //放置K个国王的方案数总和
cout<<ans<<endl;
}
int main(){
cin>>N>>K;
pre();
dp();
return 0;
}