1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <cstdio> #include <cstring>
void minify(short &a, short b) { a > b && (a = b); }
static const int N = 11; int rec[1 << 20]; short mp[N][N], f[2][N][1 << 20];
int modify(int s, int p, int v) { return (s & ((1 << (p << 1)) - 1)) | (((s >> ((p + 1) << 1) << 2) + v) << (p << 1)); }
int query(int s, int p) { return s >> (p << 1) & 3; }
int main() { int n, m, top = 0; for (int i = 0; i < 1 << 20; ++ i) { for (int j = 0; j < N; ++ j) if (query(i, j) == 1) goto illegal; rec[top ++] = i; illegal: ; } while (scanf("%d%d", &n, &m), n) { for (int i = 0; i < n; ++ i) for (int j = 0; j < m; ++ j) scanf("%hd", &mp[i][j]); int cur = 0; memset(f, 0x3f, sizeof f), f[cur][0][0] = 0; for (int i = 0; i < n; ++ i, cur ^= 1) { for (int j = 0; j < m; ++ j) for (int _ = 0, k = rec[0]; _ < top; k = rec[++ _]) if (f[cur][j][k] < 10000) { int p = query(k, j), q = query(k, j + 1); if (mp[i][j] == 0) { if (! p && ! q) minify(f[cur][j + 1][k], f[cur][j][k]), minify(f[cur][j + 1][modify(modify(k, j, 2), j + 1, 2)], f[cur][j][k] + 1), minify(f[cur][j + 1][modify(modify(k, j, 3), j + 1, 3)], f[cur][j][k] + 1); else if (! p ^ ! q) minify(f[cur][j + 1][modify(modify(k, j, p + q), j + 1, 0)], f[cur][j][k] + 1), minify(f[cur][j + 1][modify(modify(k, j, 0), j + 1, p + q)], f[cur][j][k] + 1); else if (p && p == q) minify(f[cur][j + 1][modify(modify(k, j, 0), j + 1, 0)], f[cur][j][k] + 1); } else if (mp[i][j] == 1) { if (! p && ! q) minify(f[cur][j + 1][k], f[cur][j][k]); } else { if (! p && ! q) minify(f[cur][j + 1][modify(k, j, mp[i][j])], f[cur][j][k] + 1), minify(f[cur][j + 1][modify(k, j + 1, mp[i][j])], f[cur][j][k] + 1); else if (p == mp[i][j] && ! q) minify(f[cur][j + 1][modify(k, j, 0)], f[cur][j][k] + 1); else if (! p && q == mp[i][j]) minify(f[cur][j + 1][modify(k, j + 1, 0)], f[cur][j][k] + 1); } } for (int _ = 0, k = rec[0]; _ < top; k = rec[++ _]) if (! query(k, m)) minify(f[cur ^ 1][0][k << 2 & (1 << ((m + 1) << 1)) - 1], f[cur][m][k]); for (int j = 0; j <= m; ++ j) for (int _ = 0, k = rec[0]; _ < top; k = rec[++ _]) f[cur][j][k] = 16000; } printf("%d\n", f[cur][0][0] < 10000 ? f[cur][0][0] - 2 : 0); } return 0; }
|