Problem p03056 (C++)

Buggy submission (status: Memory Limit Exceeded):
/*
ЗАПУСКАЕМ
░ГУСЯ░▄▀▀▀▄░РАБОТЯГУ░░
▄███▀░◐░░░▌░░░░░░░
░░░░▌░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▌░░░░░▐▄▄░░░░░
░░░░▌░░░░▄▀▒▒▀▀▀▀▄
░░░▐░░░░▐▒▒▒▒▒▒▒▒▀▀▄
░░░▐░░░░▐▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░▀▄░░░░▀▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░░░▀▄▄▄▄▄█▄▄▄▄▄▄▄▄▄▄▄▀▄
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░▄▄▌▌▄▌▌░░░░░
*/
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
template <typename T1, typename T2> inline void chkmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chkmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}
#define files(FILENAME)                                                        \
  read(FILENAME);                                                              \
  write(FILENAME)
#define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout)
#define all(c) (c).begin(), (c).end()
#define sz(c) (int)(c).size()
#define left left228
#define right right228
#define y1 y1228
#define mp make_pair
#define pb push_back
#define y2 y2228
#define rank rank228
const string FILENAME = "input";
const int MAXN = 190;

int h, w;
string s[MAXN];
int d[MAXN][MAXN];
int kek[MAXN][MAXN], kek1[MAXN][MAXN];

int getsum(const int &i, const int &j, const int &i1, const int &j1) {
  return d[i1][j1] - d[i1][j - 1] - d[i - 1][j1] + d[i - 1][j - 1];
}

bool check(const int &i, const int &j, const int &i1, const int &j1) {
  int s = getsum(i, j, i1, j1);
  return s == 0 || s == (j1 - j + 1) * (i1 - i + 1);
}

short dp[2][22][MAXN][MAXN][MAXN];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  // read(FILENAME);
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    cin >> s[i];
    for (int j = 0; j < w; j++) {
      d[i + 1][j + 1] = s[i][j] == '#';
    }
  }
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
    }
  }
  for (int ans = 0; ans < 20; ans++) {
    for (int k = 1; k <= h; k++) {
      for (int i = 1; i <= w; i++) {
        int uk = i;
        for (int j = i; j <= w; j++) {
          if (ans == 0) {
            for (int g = k; g <= h; g++) {
              if (check(k, i, g, j)) {
                chkmax(dp[1][ans][i][j][k], g);
              }
            }
          }
        }
      }
    }
    for (int k = 1; k <= w; k++) {
      for (int i = 1; i <= h; i++) {
        int uk = i;
        for (int j = i; j <= h; j++) {
          if (ans == 0) {
            for (int g = k; g <= w; g++) {
              if (check(i, k, j, g)) {
                chkmax(dp[0][ans][i][j][k], g);
              }
            }
          }
        }
      }
    }
    for (int i = 1; i <= h; i++) {
      for (int j = h - 1; j >= i; j--) {
        for (int k = 1; k <= w; k++) {
          chkmax(dp[0][ans][i][j][k], dp[0][ans][i][j + 1][k]);
        }
      }
    }
    for (int i = 1; i <= w; i++) {
      for (int j = w - 1; j >= i; j--) {
        for (int k = 1; k <= h; k++) {
          chkmax(dp[1][ans][i][j][k], dp[1][ans][i][j + 1][k]);
        }
      }
    }
    for (int i = 1; i <= h; i++) {
      for (int j = i; j <= h; j++) {
        for (int k = 1; k <= w; k++) {
          if (dp[0][ans][i][j][k] == 0) {
            continue;
          }
          chkmax(dp[0][ans + 1][i][j][k], dp[0][ans][i][j][k]);
          chkmax(dp[0][ans + 1][i][j][k],
                 dp[0][ans][i][j][dp[0][ans][i][j][k] + 1]);
          int x = dp[0][ans][i][j][dp[0][ans][i][j][k] + 1];
          // k, x, i, j
          chkmax(dp[1][ans + 1][k][x][i], j);
        }
      }
    }
    for (int i = 1; i <= w; i++) {
      for (int j = i; j <= w; j++) {
        for (int k = 1; k <= h; k++) {
          if (dp[1][ans][i][j][k] == 0) {
            continue;
          }
          chkmax(dp[1][ans + 1][i][j][k], dp[1][ans][i][j][k]);
          chkmax(dp[1][ans + 1][i][j][k],
                 dp[1][ans][i][j][dp[1][ans][i][j][k] + 1]);
          int x = dp[1][ans][i][j][dp[1][ans][i][j][k] + 1];
          // k, x, i, j
          chkmax(dp[0][ans + 1][k][x][i], j);
        }
      }
    }
  }
  for (int ans = 0; ans < 20; ans++) {
    if (dp[0][ans][1][h][1] >= w || dp[1][ans][1][w][1] >= h) {
      cout << ans << '\n';
      break;
    }
  }
  return 0;
}

Fixed submission:
/*
ЗАПУСКАЕМ
░ГУСЯ░▄▀▀▀▄░РАБОТЯГУ░░
▄███▀░◐░░░▌░░░░░░░
░░░░▌░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▐░░░░░▐░░░░░░░
░░░░▌░░░░░▐▄▄░░░░░
░░░░▌░░░░▄▀▒▒▀▀▀▀▄
░░░▐░░░░▐▒▒▒▒▒▒▒▒▀▀▄
░░░▐░░░░▐▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░▀▄░░░░▀▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░░░▀▄▄▄▄▄█▄▄▄▄▄▄▄▄▄▄▄▀▄
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░▄▄▌▌▄▌▌░░░░░
*/
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
template <typename T1, typename T2> inline void chkmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chkmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}
#define files(FILENAME)                                                        \
  read(FILENAME);                                                              \
  write(FILENAME)
#define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout)
#define all(c) (c).begin(), (c).end()
#define sz(c) (int)(c).size()
#define left left228
#define right right228
#define y1 y1228
#define mp make_pair
#define pb push_back
#define y2 y2228
#define rank rank228
const string FILENAME = "input";
const int MAXN = 190;

int h, w;
string s[MAXN];
int d[MAXN][MAXN];
int kek[MAXN][MAXN], kek1[MAXN][MAXN];

int getsum(const int &i, const int &j, const int &i1, const int &j1) {
  return d[i1][j1] - d[i1][j - 1] - d[i - 1][j1] + d[i - 1][j - 1];
}

bool check(const int &i, const int &j, const int &i1, const int &j1) {
  int s = getsum(i, j, i1, j1);
  return s == 0 || s == (j1 - j + 1) * (i1 - i + 1);
}

unsigned char dp[2][22][MAXN][MAXN][MAXN];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  // read(FILENAME);
  cin >> h >> w;
  for (int i = 0; i < h; i++) {
    cin >> s[i];
    for (int j = 0; j < w; j++) {
      d[i + 1][j + 1] = s[i][j] == '#';
    }
  }
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
    }
  }
  for (int ans = 0; ans < 20; ans++) {
    for (int k = 1; k <= h; k++) {
      for (int i = 1; i <= w; i++) {
        int uk = i;
        for (int j = i; j <= w; j++) {
          if (ans == 0) {
            for (int g = k; g <= h; g++) {
              if (check(k, i, g, j)) {
                chkmax(dp[1][ans][i][j][k], g);
              }
            }
          }
        }
      }
    }
    for (int k = 1; k <= w; k++) {
      for (int i = 1; i <= h; i++) {
        int uk = i;
        for (int j = i; j <= h; j++) {
          if (ans == 0) {
            for (int g = k; g <= w; g++) {
              if (check(i, k, j, g)) {
                chkmax(dp[0][ans][i][j][k], g);
              }
            }
          }
        }
      }
    }
    for (int i = 1; i <= h; i++) {
      for (int j = h - 1; j >= i; j--) {
        for (int k = 1; k <= w; k++) {
          chkmax(dp[0][ans][i][j][k], dp[0][ans][i][j + 1][k]);
        }
      }
    }
    for (int i = 1; i <= w; i++) {
      for (int j = w - 1; j >= i; j--) {
        for (int k = 1; k <= h; k++) {
          chkmax(dp[1][ans][i][j][k], dp[1][ans][i][j + 1][k]);
        }
      }
    }
    for (int i = 1; i <= h; i++) {
      for (int j = i; j <= h; j++) {
        for (int k = 1; k <= w; k++) {
          if (dp[0][ans][i][j][k] == 0) {
            continue;
          }
          chkmax(dp[0][ans + 1][i][j][k], dp[0][ans][i][j][k]);
          chkmax(dp[0][ans + 1][i][j][k],
                 dp[0][ans][i][j][dp[0][ans][i][j][k] + 1]);
          int x = dp[0][ans][i][j][dp[0][ans][i][j][k] + 1];
          // k, x, i, j
          chkmax(dp[1][ans + 1][k][x][i], j);
        }
      }
    }
    for (int i = 1; i <= w; i++) {
      for (int j = i; j <= w; j++) {
        for (int k = 1; k <= h; k++) {
          if (dp[1][ans][i][j][k] == 0) {
            continue;
          }
          chkmax(dp[1][ans + 1][i][j][k], dp[1][ans][i][j][k]);
          chkmax(dp[1][ans + 1][i][j][k],
                 dp[1][ans][i][j][dp[1][ans][i][j][k] + 1]);
          int x = dp[1][ans][i][j][dp[1][ans][i][j][k] + 1];
          // k, x, i, j
          chkmax(dp[0][ans + 1][k][x][i], j);
        }
      }
    }
  }
  for (int ans = 0; ans < 20; ans++) {
    if (dp[0][ans][1][h][1] >= w || dp[1][ans][1][w][1] >= h) {
      cout << ans << '\n';
      break;
    }
  }
  return 0;
}