状压dp板题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N =12, M = 1<<12;
ll f[N][M]; ///代表前i-1列都被填满,j代表第i列的状态
bool st[M]; ///预处理每一种状态是否合法
int n, m;
int main()
{
while(scanf("%d%d", &n, &m)&&(n+m))
{
for(int i = 0; i < (1<<n); ++i)
{
int c = 0; /// 记录连续0的个数
st[i] = 1;
for(int j = 0; j < n; ++j)
{
if(i>>j&1)
{
if(c&1) st[i] = 0;
c = 0;
}
else c++;
if(!st[i]) break;
}
if(c&1) st[i] = 0;
}
memset(f, 0, sizeof(f));
f[0][0] = 1;
for(int i = 1; i <= m; ++i)
{
for(int j = 0; j < (1<<n); ++j) //枚举第i列的状态
for(int k = 0; k < (1<<n); ++k) //枚举第i-1列的状态
{
if((j&k)==0&&st[j|k]) ///如果j和k没有冲突,且第i列的摆放不会使第i-1出现奇数的连续空格
f[i][j] += f[i-1][k];
}
}
printf("%lld\n", f[m][0]);
}
return 0;
}