注意一点 (i & j) == 0 必须记得括号
== / != 的优先级 比 & 优先级高
C++ 代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N = 12, M = 1 << N;
int n, m;
long long f[N][M];
vector <int> state[M];
bool st[M];
int main()
{
// 是一列一列地放置
while (cin >> n >> m, n || m)
{
// 第一个限制条件:当前行空位必须是偶数
for (int i=0; i < (1<<n); i++){
int cnt = 0;
bool is_valid = true;
for (int j=0; j<n; j++) {
if ((i >> j) & 1) { // 判断连续 0 的写法
if (cnt & 1) {
is_valid = false;
break;
}
cnt = 0; // 记得 cnt 置为零
} else cnt++;
}
if (cnt & 1) is_valid = false;
st[i] = is_valid;
// cout << i << " " << st[i] << endl;
}
// 第二个限制:上一行不能和至一行重叠
// state[i] 储存的是 i 这种状态可以从哪些状态转移而来
for (int i=0; i < (1<<n); i++) {
state[i].clear();
for (int j=0; j < (1<<n); j++) {
// i & j 相邻两行没有重叠
// i | j 表示上一行伸过来的叠加上自己本身的状态
// (i & j) 必须加括号
if ( ((i & j) == 0) && st[i|j])
state[i].push_back(j);
}
// cout << "i, st[i]: " << i << " " << st[i] << " cnt: " << state[i].size() <<endl;
// for (auto k: state[i]) cout << k << " ";
// cout << endl;
}
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 (auto k : state[j])
f[i][j] += f[i-1][k];
cout << f[m][0] << endl;
}
return 0;
}