
状压dp 模板
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 12, M = 1<<11;
LL f[N][M];//状态表示(f[i][j],i表示第i列,j表示以二进制存储的从第i-1列插入的状态集合)
bool st[M];//预处理时判断是否为合法状态(是否有长度为奇数的子串0)
int main(){
int n,m;
while(cin>>n>>m,n&&m){
for(int i=0;i < 1<<n;i++){//预处理st
int cnt=0;
bool flag=true;
for(int j=0;j<n;j++){
if(i>>j&1){
if(cnt&1){
flag=false;
break;
}
cnt=0;
}
else cnt++;
}
if(cnt&1) flag=false;
st[i]=flag;
}
vector<int> state[1<<n];
for(int i=0;i<1<<n;i++){
for(int j=0;j<1<<n;j++){
if((i&j)==0 && st[i|j]) state[i].push_back(j);//存储对应的合法状态
}
}
memset(f,0,sizeof f);
f[0][0]=1;//f[0][0]表示棋盘第1列中由第0列插入第1列的状态集合,(强行)算一个合法状态
for(int i=1;i<=m;i++){//每次只能使第i-1列填充完所有合法状态,所以需要多判断一列
for(int j=0;j<1<<n;j++){
for(auto k:state[j]) f[i][j]+=f[i-1][k];
}
}
cout<<f[m][0]<<endl;
}
}