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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| #include <bits/stdc++.h> using namespace std;
typedef long long ll; #define rep(i,a,n) for (ll i=a;i<(ll)(n);i++) #define per(i,a,n) for (ll i=n;i-->(ll)(a);)
ll read(){ll r;scanf("%lld",&r);return r;}
int m;
vector<int> s2v(int state){ vector<int> res = {}; rep(i,0,m) { res.push_back(state%(m+1)); state/=(m+1); } return res; }
int v2s(const vector<int>&arr){ int res = 0; per(i,0,m) { res*=(m+1); res+=arr[i]; } return res; }
vector<int> zip(const vector<int>&arr){ vector<int> res(m,0); map<int,int> v2v; int k=1; rep(i,0,m) if(arr[i] != 0) { if(!v2v.count(arr[i])){ v2v[arr[i]] = k++; } res[i] = v2v[arr[i]]; } return res; }
char s[110][10];
int main(){ int n=read(); m=read(); rep(i,0,n) scanf("%s",s[i]); vector<int> empty(m,0); array<map<int,int>,2> last; last[0][v2s(empty)] = 0;
auto samev=[&](const vector<int>&a,int j){ rep(k,0,m) if(k!=j) if(a[k]==a[j]) return true; return false; };
auto update=[&](map<int,int>&state,int st,int v) { if(!state.count(st)) state[st] = v; state[st]=min(state[st],v); };
rep(i,0,n+1) rep(j,0,m) { int black=s[i][j] == '#'; array<map<int,int>,2> nstate; rep(bf,0,2) nstate[bf]={}; rep(bf,0,2) for(auto [st,c]: last[bf]){ if(!black){ auto stv = s2v(st); if(stv[j] == 0){ update(nstate[bf],st,c); }else{ if(samev(stv,j)){ stv[j] = 0; update(nstate[bf],v2s(zip(stv)),c); }else{ if(bf == 0){ stv[j] = 0; update(nstate[bf+1],v2s(zip(stv)),c); } } } } auto stv = s2v(st); int top = stv[j]; int left = j==0?0:stv[j-1]; if(top == 0 and left == 0){ auto tmpv = stv; tmpv[j] = m+1; update(nstate[bf],v2s(zip(tmpv)),c+!black); }else if(left == 0){ update(nstate[bf],st,c+!black); }else if(top == 0){ auto tmpv = stv; tmpv[j] = left; update(nstate[bf],v2s(zip(tmpv)),c+!black); }else{ auto tmpv = stv; rep(k,0,m) if(tmpv[k] == left) tmpv[k] = top; update(nstate[bf],v2s(zip(tmpv)),c+!black); } } rep(bf,0,2) swap(last[bf],nstate[bf]); } printf("%d\n",last[1][v2s(empty)]); return 0; }
|