Problem p01431 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vv;
typedef pair<int, int> P;
vi con[279];      // 6th Bell number
map<vi, int> inv; // inv of con
int mx_[279];
int bits[234];         // 11th Fibonacci number
vector<P> bitcon[234]; // 11010 -> {(0,2),(3,4)}
int nxt[279][234][234];
int C; // con
int B; // bits
int H, W;
string s[11];
int dp[12][279][234];
vi tmp;
void dfs(int x, int mx) {
  con[C] = tmp;
  mx_[C] = mx;
  inv[tmp] = C++;
  //	printf("c=%d:  ",C-1);
  //	for(int a:tmp) cout<<a<<" ";
  //	puts("");
  if (x == 6)
    return;
  rep(i, mx + 1) {
    tmp.pb(i);
    dfs(x + 1, max(mx, i + 1));
    tmp.pop_back();
  }
}
inline int cntbit(int x) {
  if (x == 0)
    return 0;
  return __builtin_popcount(x);
}
int par[12];
void init(int N) { rep(i, N) par[i] = i; }
int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}
bool same(int x, int y) { return find(x) == find(y); }
void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x < y)
    swap(x, y);
  par[x] = y;
}
inline bool _b(int x, int y) { return ((x >> y) & 1) == 1; }
bool is(P x, P y) { return x.fs < y.sc && y.fs < x.sc; }
int main() {
  dfs(0, 0);
  cin >> H >> W;
  rep(i, H) cin >> s[i];
  if (W == 1) {
    if (H == 1) {
      if (s[0][0] == '.')
        puts("0");
      else
        puts("1");
      return 0;
    }
    rep1(i, H - 1) s[0] += s[i][0];
    swap(H, W);
  }
  rep(i, 1 << W) {
    bool ok = 1;
    rep(j, W - 1) if (!_b(i, j) && !_b(i, j + 1)) ok = 0;
    if (ok || i == 0) {
      bits[B] = i;
      //			printf("bits[%d]=%d\n",B,i);
      int p = -1;
      vector<P> vp;
      rep(j, W + 1) {
        if (_b(i, j)) {
          if (p < 0)
            p = j;
        } else {
          if (p >= 0) {
            vp.pb(P(p, j));
            p = -1;
          }
        }
      }
      bitcon[B++] = vp;
      //			show(vp.size());
    }
  }
  //	show(B);
  rep(i, C) rep(j, B) rep(k, B) nxt[i][j][k] = -1;
  rep(i, C) {
    vi &vc = con[i];
    int sz = vc.size();
    rep(j, B) {
      int &b = bits[j];
      vector<P> &bc = bitcon[j];
      if (bc.size() != sz)
        continue;
      rep(k, B) {
        int &nb = bits[k];
        vector<P> &nbc = bitcon[k];
        int nsz = nbc.size();
        if ((b | nb) != (1 << W) - 1 && j > 0)
          continue;
        bool ok = 1;
        rep(d, W - 1) if (_b(b, d) && _b(b, d + 1) && _b(nb, d) &&
                          _b(nb, d + 1)) ok = 0;
        if (j > 0 && !ok)
          continue;
        //				if(i==4&&j==6&&k==10) puts("---!!---");
        //				if(i==4&&j==6&&k==10) show(sz);
        //				if(i==4&&j==6&&k==10) show(nsz);
        init(sz + nsz);
        rep(d, sz) rep(e, sz) {
          if (vc[d] == vc[e]) {
            unite(d + nsz, e + nsz);
            //						if(i==4&&j==6&&k==10)
            //printf("%d-%d\n",d+nsz,e+nsz);
          }
        }
        bool used[6] = {};
        rep(d, sz) rep(e, nsz) {
          if (is(bc[d], nbc[e])) {
            if (same(d + nsz, e)) {
              ok = 0;
              goto done;
            }
            unite(d + nsz, e);
            //						if(i==4&&j==6&&k==10)
            //printf("%d-%d\n",d+nsz,e);
            used[vc[d]] = 1;
          }
        }
      done:
        if (ok) {
          //				printf("'nxt[%d][%d][%d]=ok\n",i,j,k);
          rep(d, mx_[i]) if (!used[d]) ok = 0;
          if (!ok)
            continue;
          vi nvc;
          map<int, int> mp;
          int Z = 0;
          rep(d, nsz) if (mp.count(find(d)) == 0) mp[find(d)] = Z++;
          rep(d, nsz) nvc.pb(mp[find(d)]);
          if (inv.count(nvc) == 0) {
            show(nsz);
            for (int a : nvc)
              cout << a << " ";
            assert(false);
          }
          nxt[i][j][k] = inv[nvc];
          //					printf("nxt[%d][%d][%d]=%d\n",i,j,k,nxt[i][j][k]);
          //					for(int a:nvc) cout<<a<<" ";
          //					puts("");
        }
      }
    }
  }
  if (W == 1)
    nxt[1][1][0] = 0;
  rep(i, H + 1) rep(j, C) rep(k, B) dp[i][j][k] = -1;
  dp[0][0][0] = 0;
  rep(i, H) {
    bool canuse[234] = {};
    rep(k, B) {
      bool ok = 1;
      rep(x, W) {
        if (s[i][x] == '#' && !_b(bits[k], x))
          ok = 0;
        if (s[i][x] == '.' && _b(bits[k], x))
          ok = 0;
      }
      canuse[k] = ok;
      //			if(ok) printf("canuse[%d]=%d\n",k,ok);
    }
    rep(j, C) rep(k, B) {
      if (dp[i][j][k] < 0)
        continue;
      //			printf("i,j,k=(%d,%d,%d)\n",i,j,k);
      if (i > 0 && k == 0 && W > 1)
        continue;
      rep(l, B) {
        if (!canuse[l])
          continue;
        if (W > 1 && l == 0)
          continue;
        //				printf("  i,j,k=(%d,%d,%d)\n",i,j,k);
        //				show(l);
        //				show(nxt[j][k][l]);
        if (nxt[j][k][l] >= 0) {
          chmax(dp[i + 1][nxt[j][k][l]][l], dp[i][j][k] + cntbit(bits[l]));
          //					printf("dp[%d][%d][%d],dp[%d][%d][%d]+%d\n",i+1,nxt[j][k][l],l,i,j,k,cntbit(bits[l]));
        }
      }
    }
  }
  int ans = -1;
  rep(j, C) {
    bool ok = 1;
    rep(k, con[j].size()) if (con[j][k] > 0) ok = 0;
    if (!ok)
      continue;
    //		show(j);
    rep(k, B) {
      chmax(ans, dp[H][j][k]);
      //			printf("dp[%d][%d][%d]=%d\n",H,j,k,dp[H][j][k]);
    }
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vv;
typedef pair<int, int> P;
vi con[279];      // 6th Bell number
map<vi, int> inv; // inv of con
int mx_[279];
int bits[234];         // 11th Fibonacci number
vector<P> bitcon[234]; // 11010 -> {(0,2),(3,4)}
short int nxt[279][234][234];
int C; // con
int B; // bits
int H, W;
string s[11];
int dp[12][279][234];
vi tmp;
void dfs(int x, int mx) {
  con[C] = tmp;
  mx_[C] = mx;
  inv[tmp] = C++;
  //	printf("c=%d:  ",C-1);
  //	for(int a:tmp) cout<<a<<" ";
  //	puts("");
  if (x == 6)
    return;
  rep(i, mx + 1) {
    tmp.pb(i);
    dfs(x + 1, max(mx, i + 1));
    tmp.pop_back();
  }
}
inline int cntbit(int x) {
  if (x == 0)
    return 0;
  return __builtin_popcount(x);
}
int par[12];
void init(int N) { rep(i, N) par[i] = i; }
int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}
bool same(int x, int y) { return find(x) == find(y); }
void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x < y)
    swap(x, y);
  par[x] = y;
}
inline bool _b(int x, int y) { return ((x >> y) & 1) == 1; }
bool is(P x, P y) { return x.fs < y.sc && y.fs < x.sc; }
int main() {
  dfs(0, 0);
  cin >> H >> W;
  rep(i, H) cin >> s[i];
  if (W == 1) {
    if (H == 1) {
      if (s[0][0] == '.')
        puts("0");
      else
        puts("1");
      return 0;
    }
    rep1(i, H - 1) s[0] += s[i][0];
    swap(H, W);
  }
  rep(i, 1 << W) {
    bool ok = 1;
    rep(j, W - 1) if (!_b(i, j) && !_b(i, j + 1)) ok = 0;
    if (ok || i == 0) {
      bits[B] = i;
      //			printf("bits[%d]=%d\n",B,i);
      int p = -1;
      vector<P> vp;
      rep(j, W + 1) {
        if (_b(i, j)) {
          if (p < 0)
            p = j;
        } else {
          if (p >= 0) {
            vp.pb(P(p, j));
            p = -1;
          }
        }
      }
      bitcon[B++] = vp;
      //			show(vp.size());
    }
  }
  //	show(B);
  rep(i, C) rep(j, B) rep(k, B) nxt[i][j][k] = -1;
  rep(i, C) {
    vi &vc = con[i];
    int sz = vc.size();
    rep(j, B) {
      int &b = bits[j];
      vector<P> &bc = bitcon[j];
      if (bc.size() != sz)
        continue;
      rep(k, B) {
        int &nb = bits[k];
        vector<P> &nbc = bitcon[k];
        int nsz = nbc.size();
        if ((b | nb) != (1 << W) - 1 && j > 0)
          continue;
        bool ok = 1;
        rep(d, W - 1) if (_b(b, d) && _b(b, d + 1) && _b(nb, d) &&
                          _b(nb, d + 1)) ok = 0;
        if (j > 0 && !ok)
          continue;
        //				if(i==4&&j==6&&k==10) puts("---!!---");
        //				if(i==4&&j==6&&k==10) show(sz);
        //				if(i==4&&j==6&&k==10) show(nsz);
        init(sz + nsz);
        rep(d, sz) rep(e, sz) {
          if (vc[d] == vc[e]) {
            unite(d + nsz, e + nsz);
            //						if(i==4&&j==6&&k==10)
            //printf("%d-%d\n",d+nsz,e+nsz);
          }
        }
        bool used[6] = {};
        rep(d, sz) rep(e, nsz) {
          if (is(bc[d], nbc[e])) {
            if (same(d + nsz, e)) {
              ok = 0;
              goto done;
            }
            unite(d + nsz, e);
            //						if(i==4&&j==6&&k==10)
            //printf("%d-%d\n",d+nsz,e);
            used[vc[d]] = 1;
          }
        }
      done:
        if (ok) {
          //				printf("'nxt[%d][%d][%d]=ok\n",i,j,k);
          rep(d, mx_[i]) if (!used[d]) ok = 0;
          if (!ok)
            continue;
          vi nvc;
          map<int, int> mp;
          int Z = 0;
          rep(d, nsz) if (mp.count(find(d)) == 0) mp[find(d)] = Z++;
          rep(d, nsz) nvc.pb(mp[find(d)]);
          if (inv.count(nvc) == 0) {
            show(nsz);
            for (int a : nvc)
              cout << a << " ";
            assert(false);
          }
          nxt[i][j][k] = inv[nvc];
          //					printf("nxt[%d][%d][%d]=%d\n",i,j,k,nxt[i][j][k]);
          //					for(int a:nvc) cout<<a<<" ";
          //					puts("");
        }
      }
    }
  }
  if (W == 1)
    nxt[1][1][0] = 0;
  rep(i, H + 1) rep(j, C) rep(k, B) dp[i][j][k] = -1;
  dp[0][0][0] = 0;
  rep(i, H) {
    bool canuse[234] = {};
    rep(k, B) {
      bool ok = 1;
      rep(x, W) {
        if (s[i][x] == '#' && !_b(bits[k], x))
          ok = 0;
        if (s[i][x] == '.' && _b(bits[k], x))
          ok = 0;
      }
      canuse[k] = ok;
      //			if(ok) printf("canuse[%d]=%d\n",k,ok);
    }
    rep(j, C) rep(k, B) {
      if (dp[i][j][k] < 0)
        continue;
      //			printf("i,j,k=(%d,%d,%d)\n",i,j,k);
      if (i > 0 && k == 0 && W > 1)
        continue;
      rep(l, B) {
        if (!canuse[l])
          continue;
        if (W > 1 && l == 0)
          continue;
        //				printf("  i,j,k=(%d,%d,%d)\n",i,j,k);
        //				show(l);
        //				show(nxt[j][k][l]);
        if (nxt[j][k][l] >= 0) {
          chmax(dp[i + 1][nxt[j][k][l]][l], dp[i][j][k] + cntbit(bits[l]));
          //					printf("dp[%d][%d][%d],dp[%d][%d][%d]+%d\n",i+1,nxt[j][k][l],l,i,j,k,cntbit(bits[l]));
        }
      }
    }
  }
  int ans = -1;
  rep(j, C) {
    bool ok = 1;
    rep(k, con[j].size()) if (con[j][k] > 0) ok = 0;
    if (!ok)
      continue;
    //		show(j);
    rep(k, B) {
      chmax(ans, dp[H][j][k]);
      //			printf("dp[%d][%d][%d]=%d\n",H,j,k,dp[H][j][k]);
    }
  }
  cout << ans << endl;
}