经典的状压DP.
AC code:
#include <cstdio>
const int N=10;
const int M=1<<10;
typedef long long ll;
int n,m;
int tot[M];
ll ans;
ll f[N][M][N*N];
bool wrng[M];
bool ok[M][M];
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<(1<<n);i++){
if(i&(i<<1)){
wrng[i]=1;
continue;
}
int t=i;
while(t){
tot[i]+=t&1;
t>>=1;
}
}
for(int i=0;i<(1<<n);i++){
for(int j=0;j<(1<<n);j++){
if(wrng[i]||wrng[j]) continue;
if(!(i&j)&&!((i<<1)&j)&&!((i>>1)&j)) ok[i][j]=1;
}
}
for(int i=0;i<(1<<n);i++){
if(!wrng[i]) f[1][i][tot[i]]=1;
}
for(int i=2;i<=n;i++){
for(int j=0;j<(1<<n);j++){
if(wrng[j]) continue;
for(int k=tot[j];k<=m;k++){
for(int jj=0;jj<(1<<n);jj++){
if(ok[j][jj]) f[i][j][k]+=f[i-1][jj][k-tot[j]];
}
}
}
}
for(int i=0;i<(1<<n);i++){
if(wrng[i]) continue;
ans+=f[n][i][m];
}
printf("%lld",ans);
return 0;
}