Problem p03056 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
const int N = 188;
int dp[N][N][N][20];
int sum[N][N];
char c[N][N];
int n, m;
inline int cal(int x, int y, int l, int r) {
  return sum[r][y] + sum[l - 1][x - 1] - sum[l - 1][y] - sum[r][x - 1];
}
inline bool no_cost(int x, int y, int l, int r) {
  if (cal(x, y, l, r) == 0 || cal(x, y, l, r) == (y - x + 1) * (r - l + 1))
    return true;
  return false;
}

int dfs(int x, int l, int r, int k) {
  if (dp[x][l][r][k] != -1)
    return dp[x][l][r][k];
  if (l > r || x <= 0 || x > m)
    return x;
  int nxt = dfs(x, l, r, k - 1);
  if (nxt != m && nxt >= x)
    dp[x][l][r][k] = dfs(nxt + 1, l, r, k - 1);
  else
    dp[x][l][r][k] = nxt;
  int L = 0, R = r - l;
  while (L <= R) {
    int mid = (L + R) >> 1;
    int Le = dfs(x, l, l + mid, k - 1);
    int Ri = dfs(x, l + mid + 1, r, k - 1);
    dp[x][l][r][k] = max(dp[x][l][r][k], min(Le, Ri));
    if (Le <= Ri && Le != -1)
      R = mid - 1;
    else
      L = mid + 1;
  }
  return dp[x][l][r][k];
}
int main() {
  memset(dp, -1, sizeof(dp));
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cin >> c[i][j];
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (c[i][j] == '.');
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = i; j <= n; ++j) {
      int last = 1, k = 1;
      while (k <= m) {
        while (k <= m && no_cost(last, k, i, j))
          k++;
        if (last == k) {
          dp[last][i][j][0] = 0;
          k = ++last;
        }
        for (; last < k; last++)
          dp[last][i][j][0] = k - 1;
      }
    }
  }
  for (int i = 0; i <= 18; i++) {
    if (dfs(1, 1, n, i) == m) {
      cout << i << endl;
      return 0;
    }
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
const int N = 187;
int dp[N][N][N][18];
int sum[N][N];
char c[N][N];
int n, m;
inline int cal(int x, int y, int l, int r) {
  return sum[r][y] + sum[l - 1][x - 1] - sum[l - 1][y] - sum[r][x - 1];
}
inline bool no_cost(int x, int y, int l, int r) {
  if (cal(x, y, l, r) == 0 || cal(x, y, l, r) == (y - x + 1) * (r - l + 1))
    return true;
  return false;
}

int dfs(int x, int l, int r, int k) {
  if (dp[x][l][r][k] != -1)
    return dp[x][l][r][k];
  if (l > r || x <= 0 || x > m)
    return x;
  int nxt = dfs(x, l, r, k - 1);
  if (nxt != m && nxt >= x)
    dp[x][l][r][k] = dfs(nxt + 1, l, r, k - 1);
  else
    dp[x][l][r][k] = nxt;
  int L = 0, R = r - l;
  while (L <= R) {
    int mid = (L + R) >> 1;
    int Le = dfs(x, l, l + mid, k - 1);
    int Ri = dfs(x, l + mid + 1, r, k - 1);
    dp[x][l][r][k] = max(dp[x][l][r][k], min(Le, Ri));
    if (Le <= Ri && Le != -1)
      R = mid - 1;
    else
      L = mid + 1;
  }
  return dp[x][l][r][k];
}
int main() {
  memset(dp, -1, sizeof(dp));
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      cin >> c[i][j];
      sum[i][j] =
          sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (c[i][j] == '.');
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = i; j <= n; ++j) {
      int last = 1, k = 1;
      while (k <= m) {
        while (k <= m && no_cost(last, k, i, j))
          k++;
        if (last == k) {
          dp[last][i][j][0] = 0;
          k = ++last;
        }
        for (; last < k; last++)
          dp[last][i][j][0] = k - 1;
      }
    }
  }
  for (int i = 0; i <= 18; i++) {
    if (dfs(1, 1, n, i) == m) {
      cout << i << endl;
      return 0;
    }
  }
  return 0;
}