int n, m; // state 记录所有合法状态 vector<int> state; // cnt[i] 记录状态 i 中包含多少个 1 int cnt[M]; // head[i] 记录所有可以转移到状态 i 的状态 vector<int> head[M]; // DP 数组 LL f[N][K][M];
// 检查一个状态是不是合法状态 boolcheck(int state){ for (int i = 0; i < n; i++) { if ((state >> i & 1) && (state >> i + 1 & 1)) { returnfalse; } } returntrue; }
// 计算一个状态中 1 的个数 intcount(int state){ int res = 0; for (int i = 0; i < n; i++) res += state >> i & 1; return res; }
intmain(){ cin >> n >> m; // 将所有合法状态与处理出来,同时记录这个状态里包含多少个 1 for (int i = 0; i < 1 << n; i++) { if (check(i)) { state.push_back(i); cnt[i] = count(i); } } // 两两比较每个状态,记录每个状态可以由哪些状态转移过来 for (int i = 0; i < state.size(); i++) { for (int j = 0; j < state.size(); j++) { int a = state[i], b = state[j]; if ((a & b) == 0 && check(a | b)) { head[i].push_back(j); } } } // 初始化,不摆任何国王也算一种摆法,所以初始化成 1 f[0][0][0] = 1; // 枚举行数 for (int i = 1; i <= n + 1; i++) { // 枚举摆了几个国王 for (int j = 0; j <= m; j++) { // 枚举最后一行可能的状态 for (int a = 0; a < state.size(); a++) { // 枚举所有可以转移到当前状态的那些状态,也就是 i-1 行的状态 for (int b : head[a]) { int c = cnt[state[a]]; if (j >= c) { // 最后一行摆的国王的数量不能超过当前考虑的国王数目 f[i][j][a] += f[i - 1][j - c][b]; } } } } } cout << f[n + 1][m][0] << endl; return0; }
int n, m; int g[N]; vector<int> state; vector<int> head[M]; int f[N][M];
boolcheck(int state){ for (int i = 0; i < m; i++) { if ((state >> i & 1) && (state >> i + 1 & 1)) { returnfalse; } } returntrue; }
intmain(){ cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 0; j < m; j++) { int t; cin >> t; g[i] += !t << j; } } for (int i = 0; i < 1 << m; i++) { if (check(i)) { state.push_back(i); } } for (int i = 0; i < state.size(); i++) { for (int j = 0; j < state.size(); j++) { int a = state[i], b = state[j]; if ((a & b) == 0) { head[i].push_back(j); } } } f[0][0] = 1; for (int i = 1; i <= n + 1; i++) { for (int a = 0; a < state.size(); a++) { for (int b : head[a]) { if (g[i] & state[a]) continue; f[i][a] = (f[i][a] + f[i - 1][b]) % mod; } } } cout << f[n + 1][0] << endl; return0; }
int n, m; int g[110]; vector<int> state; int cnt[M]; int f[2][M][M];
boolcheck(int state){ for (int i = 0; i < m; i++) { if ((state >> i & 1) && ((state >> i + 1 & 1) || (state >> i + 2 & 1))) { returnfalse; } } returntrue; }
intcount(int state){ int res = 0; for (int i = 0; i < m; i++) { res += state >> i & 1; } return res; }
intmain(){ cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 0; j < m; j++) { char c; cin >> c; if (c == 'H') { g[i] += 1 << j; } } }
for (int i = 0; i < 1 << m; i++) { if (check(i)) { state.push_back(i); cnt[i] = count(i); } }
for (int i = 1; i <= n + 2; i++) { // 枚举第 i - 1 行状态 for (int j = 0; j < state.size(); j++) { // 枚举第 i 行状态 for (int k = 0; k < state.size(); k++) { // 枚举第 i - 2 行的状态 for (int u = 0; u < state.size(); u++) { int a = state[j], b = state[k], c = state[u]; // 三行之间两两不能有交集 if ((a & b) | (b & c) | (a & c)) continue; // 大炮不能部署在山上 if (g[i - 1] & a | g[i] & b) continue; f[i & 1][j][k] = max(f[i & 1][j][k], f[i - 1 & 1][u][j] + cnt[b]); } } } } cout << f[n + 2 & 1][0][0] << endl; return0; }