状压DP
记f[i][j][k]表示第i行,已经摆放了j个,第i行的状态为k的方案数。
#include<cstdio>
#define MAXN 11
#define MAXC 100
long long f[MAXN][MAXC][1<<MAXN], q[1000][2], tot=0;
int main()
{
int n, k;
scanf("%d%d",&n,&k);
for(int i = 0, limit=1<<n; i < limit; i++)
{
int cnt=0, t=i;
if(t&(t<<1))continue;
while(t>0)
{
cnt+=1&t;
t>>=1;
}
q[++tot][0]=i;
q[tot][1]=cnt;
}
for(int i = 1; i <= tot; i++)
f[1][q[i][1]][q[i][0]]=1;
for(int i = 1; i < n; i++)
{
for(int j = 1; j <= tot; j++)
{
int p1=q[j][0];
for(int k = 1; k<= tot; k++)
{
int p2=q[k][0], t2=q[k][1];
if(p1&p2 || p1&(p2<<1) || (p1<<1)&p2)continue;
for(int g = t2; g < MAXC; g++)
f[i+1][g][p2]+=f[i][g-t2][p1];
}
}
}
long long ans=0;
for(int j = 1; j <= tot; j++)
ans+=f[n][k][q[j][0]];
printf("%lld\n",ans);
return 0;
}