题解
炸弹人
1 条题解
-
0
#include <bits/stdc++.h> using namespace std; int n, m, g[105], dp[105][100][100]; vector<int> s; // 保存每一行合法的状态 void init_state() { // 预处理出每一行合法的状态 for(int i = 0; i < (1 << m); ++i) { if(i & (i >> 1) || i & (i >> 2)) continue; s.push_back(i); } } bool check(int x) { return x & (x >> 1); // 同一行有相邻的1 } int get_cnt(int x, int sta) { // 第x行状态为sta时可以波及到的方格数量 int ans = 0, flag = 0; for(int i = 0; i < m; ++i) { if((sta >> i) & 1) { flag = 1; if(x - 1 >= 1) ++ans; if(x + 1 <= n) ++ans; if(i - 1 >= 0) ++ans; if(i + 1 < m) ++ans; } } return ans + flag; } int main() { cin>>n>>m; for(int i = 1; i <= n; ++i) { // 处理出每一行的状态g[i] for(int j = 1; j <= m; ++j) { char ch; cin>>ch; if(ch == 'A') g[i] = (g[i] << 1) + 1; else g[i] = (g[i] << 1) + 0; } } init_state(); // 筛选每行合法的状态 dp[0][0][0] = 0; for(int i = 1; i <= n + 2; ++i) { for(int j = 0; j < s.size(); ++j) { // 第i行状态 for(int k = 0; k < s.size(); ++k) { // 第i-1行状态 for(int u = 0; u < s.size(); ++u) { // 第i-2行状态 int a = s[u], b = s[k], c = s[j]; if(a & b || b & c || a & c) continue; if(g[i] & c || g[i - 1] & b) continue; if(check(b | c)) continue; // 左上与右上 int cnt = 0; // 第i行状态波及到的炸弹数 if(i <= n) cnt = get_cnt(i, c); dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][u] + cnt); } } } } cout<<dp[n + 2][0][0]; return 0; }
- 1