状态压缩DP
蒙特里安的梦想
放弃,参考大佬博客吧,
#include<bits/stdc++.h>
using namespace std;
const int N = 12, M = 1 << N;
long long f[N][M]; // 第一维表示列, 第二维表示所有可能的状态
/*
f[i][j]:表示第i列中,横着摆放占据的位置状态为j的摆放总数
*/
bool st[M]; // st[i] == true:表示状态i是合法的状态, 存储每种状态是否有奇数个连续的0,如果奇数个0是无效状态,如果是偶数个零置为true。
vector<int> state[M]; // state[i]指状态i的情况下,我们能接受的前一列伸出来的所有状态,存入vector中
int n, m;
int main(){
while(cin >> n >> m, n || m){
for(int i = 0; i < 1 << n; ++i){
int cnt = 0;
for(int j = 0; j < n; ++j){
if(i >> j & 1 != 0){
if(cnt & 1) break;
}
else cnt++;
}
// cout << "i : " << i << " cnt & 1: " << (cnt & 1) << endl;
if(cnt & 1) st[i] = false;
else st[i] = true;
}
// puts("");
// for(int i = 0; i < 1 << n; ++i) printf("%d\t", i);
// puts("");
// for(int i = 0; i < 1 << n; ++i) printf("%d\t", st[i]);
for(int i = 0; i < 1 << n; ++i){
state[i].clear();
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;
for(int i = 1; i <= m; ++i){
for(int j = 0; j < 1 << n; ++j){
for(int k = 0; k < state[j].size(); ++k){
f[i][j] += f[i - 1][state[j][k]];
}
}
}
printf("%lld\n", f[m][0]);
}
return 0;
}