经典的状态压缩dp每个格子分三种状态(下面的格子为当前格),如图所示,分别用0,1,2表示
然后利用上一行的合法状态推导出当前行的一个基本状态(黑书上有详解),在该基本状态上,枚举可能的方案,更新表格
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::istringstream; using std::make_pair; using std::greater; using std::endl; const int INFI((INT_MAX-1) >> 1); const int MAXN(160); const int MAXM(11); bool mp[MAXN][MAXM]; int table[2][60000]; int pow3[12]; int N, M, K; int cur, last; int as1[11], as2[11]; void updata(int n, int st1, int &st2) { st2 = 0; for(int i = 0; i < M; ++i) { as1[i] = st1%3; if(mp[n][i]) { if(as1[i] == 2) { as2[i] = 1; st2 += 1*pow3[i]; } else { as2[i] = 0; st2 += 0; } } else { as2[i] = 2; st2 += 2*pow3[i]; } st1 /= 3; } } void dfs(int n, int m, int st, int value) { if(value > table[cur][st]) table[cur][st] = value; if(m <= M-2 && as2[m] == 0 && as2[m+1] == 0 && as1[m] == 0 && as1[m+1] == 0) { as2[m] = 2; as2[m+1] = 2; dfs(n, m+2, st+pow3[m]*2+pow3[m+1]*2, value+1); as2[m] = 0; as2[m+1] = 0; } if(m <= M-3 && as2[m] == 0 && as2[m+1] == 0 && as2[m+2] == 0) { as2[m] = 2; as2[m+1] = 2; as2[m+2] = 2; dfs(n, m+3, st+pow3[m]*2+pow3[m+1]*2+pow3[m+2]*2, value+1); as2[m] = 0; as2[m+1] = 0; as2[m+2] = 0; } if(m <= M-1) dfs(n, m+1, st, value); } int main() { pow3[0] = 1; for(int i = 1; i <= 11; ++i) pow3[i] = pow3[i-1]*3; int T; scanf("%d", &T); while(T--) { scanf("%d%d%d", &N, &M, &K); memset(mp, 0, sizeof(mp)); for(int i = 1; i <= N; ++i) for(int j = 0; j < M; ++j) mp[i][j] = true; int x, y; for(int i = 0; i < K; ++i) { scanf("%d%d", &x, &y); mp[x][y-1] = false; } cur = 0; last = 1; memset(table[last], -1, sizeof(table[last])); int temp = 0; for(int i = 0; i < M; ++i) if(mp[1][i]) temp += pow3[i]*1; else temp += pow3[i]*2; table[last][temp] = 0; for(int i = 2; i <= N; ++i) { memset(table[cur], -1, sizeof(table[cur])); for(int j = 0; j < pow3[M]; ++j) if(table[last][j] != -1) { int st2; updata(i, j, st2); dfs(i, 0, st2, table[last][j]); } cur ^= 1; last ^= 1; } int ans = 0; for(int i = 0; i < pow3[M]; ++i) if(table[last][i] > ans) ans = table[last][i]; printf("%d\n", ans); } return 0; }