Problem p03056 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> P;
typedef pair<int, P> P1;

typedef unsigned char uc;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i, x) for (int i = 0; i < x; i++)
#define rep1(i, x) for (int i = 1; i <= x; i++)
#define rrep(i, x) for (int i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (int i = x; i > 0; i--)
#define sor(v) sort(v.begin(), v.end())
#define rev(s) reverse(s.begin(), s.end())
#define lb(vec, a) lower_bound(vec.begin(), vec.end(), a)
#define ub(vec, a) upper_bound(vec.begin(), vec.end(), a)
#define uniq(vec) vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define mp1(a, b, c) P1(a, P(b, c))

const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

// uc dp[400000010];

/*int ind(int i,int j,int k,int l){
        return ((372-i)*(i-1)/2+j-i)*93*185+((372-k)*(k-1)/2+l-k);
}*/

int main() {
  int h, w;
  char c[200][200];
  scanf("%d%d", &h, &w);
  rep1(i, h) {
    scanf("\n");
    rep1(j, w) scanf("%c", &c[i][j]);
  }

  /*rep1(i,h)for(int j = i ; j <= h ; j ++){
          rep1(k,w)for(int l = k ; l <= w ; l ++){
                  dp[ind(i,j,k,l)] = 0;
          }
  }*/

  static unsigned char dp1[200][200][200][20];
  static unsigned char dp2[200][200][200][20];
  int dp_memo[200][200];

  rrep1(x, h) rrep1(y, w) {
    for (int i = x; i <= h; i++) {
      for (int j = y; j <= w; j++) {
        dp_memo[i][j] = 100;
      }
    }
    for (int i = x; i <= h; i++) {
      for (int j = y; j <= w; j++) {
        if ((j == y || dp_memo[i][j - 1] == 0) &&
            (i == x || dp_memo[i - 1][j] == 0) && c[x][y] == c[i][j]) {
          dp_memo[i][j] = 0;
        }
        if (dp_memo[i][j] != 100) {
          if (j == w || dp_memo[i][j + 1] > dp_memo[i][j]) {
            int s = dp_memo[i][j];
            int t = dp1[x][j + 1][i][dp_memo[i][j]];
            while (t == 0 && s < 19) {
              s++;
              t = dp1[x][j + 1][i][s];
            }
            if (t != 0) {
              while (dp_memo[i][t] > s + 1) {
                dp_memo[i][t] = s + 1;
                t--;
              }
            }
          }
          if (i == h || dp_memo[i + 1][j] > dp_memo[i][j]) {
            int s = dp_memo[i][j];
            int t = dp2[i + 1][y][j][dp_memo[i][j]];
            while (t == 0 && s < 19) {
              s++;
              t = dp2[i + 1][y][j][s];
            }
            if (t != 0) {
              while (dp_memo[t][j] > s + 1) {
                dp_memo[t][j] = s + 1;
                t--;
              }
            }
          }
        }
      }
    }
    for (int i = x; i <= h; i++) {
      rep(k, 20) dp1[x][y][i][k] = 0;
    }
    for (int j = y; j <= w; j++) {
      rep(k, 20) dp2[x][y][j][k] = 0;
    }
    for (int i = x; i <= h; i++) {
      for (int j = w; j >= y; j--) {
        if (dp_memo[i][j] == 100)
          continue;
        if (dp1[x][y][i][dp_memo[i][j]] == 0)
          dp1[x][y][i][dp_memo[i][j]] = j;
      }
      rep(k, 19) dp1[x][y][i][k + 1] =
          max(dp1[x][y][i][k], dp1[x][y][i][k + 1]);
    }
    for (int j = y; j <= w; j++) {
      for (int i = h; i >= x; i--) {
        if (dp_memo[i][j] == 100)
          continue;
        if (dp2[x][y][j][dp_memo[i][j]] == 0)
          dp2[x][y][j][dp_memo[i][j]] = i;
      }
      rep(k, 19) dp2[x][y][j][k + 1] =
          max(dp2[x][y][j][k], dp2[x][y][j][k + 1]);
    }
  }

  /*rep(k,19){
          cout << dp1[h][w][h][k] << endl;
  }*/

  rep(k, 19) {
    // cout << dp1[1][1][h][k] << endl;
    if (dp1[1][1][h][k] == w) {
      cout << k << endl;
      return 0;
    }
  }
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> P;
typedef pair<int, P> P1;

typedef unsigned char uc;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i, x) for (int i = 0; i < x; i++)
#define rep1(i, x) for (int i = 1; i <= x; i++)
#define rrep(i, x) for (int i = x - 1; i >= 0; i--)
#define rrep1(i, x) for (int i = x; i > 0; i--)
#define sor(v) sort(v.begin(), v.end())
#define rev(s) reverse(s.begin(), s.end())
#define lb(vec, a) lower_bound(vec.begin(), vec.end(), a)
#define ub(vec, a) upper_bound(vec.begin(), vec.end(), a)
#define uniq(vec) vec.erase(unique(vec.begin(), vec.end()), vec.end())
#define mp1(a, b, c) P1(a, P(b, c))

const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

// uc dp[400000010];

/*int ind(int i,int j,int k,int l){
        return ((372-i)*(i-1)/2+j-i)*93*185+((372-k)*(k-1)/2+l-k);
}*/

int main() {
  int h, w;
  char c[200][200];
  scanf("%d%d", &h, &w);
  rep1(i, h) {
    scanf("\n");
    rep1(j, w) scanf("%c", &c[i][j]);
  }

  /*rep1(i,h)for(int j = i ; j <= h ; j ++){
          rep1(k,w)for(int l = k ; l <= w ; l ++){
                  dp[ind(i,j,k,l)] = 0;
          }
  }*/

  static unsigned char dp1[200][200][200][20];
  static unsigned char dp2[200][200][200][20];
  int dp_memo[200][200];

  rrep1(x, h) rrep1(y, w) {
    for (int i = x; i <= h; i++) {
      for (int j = y; j <= w; j++) {
        dp_memo[i][j] = 100;
      }
    }
    for (int i = x; i <= h; i++) {
      for (int j = y; j <= w; j++) {
        if ((j == y || dp_memo[i][j - 1] == 0) &&
            (i == x || dp_memo[i - 1][j] == 0) && c[x][y] == c[i][j]) {
          dp_memo[i][j] = 0;
        }
      }
    }
    for (int i = x; i <= h; i++) {
      for (int j = y; j <= w; j++) {
        /*if((j == y || dp_memo[i][j-1] == 0) && (i == x || dp_memo[i-1][j] ==
        0) && c[x][y] == c[i][j]){ dp_memo[i][j] = 0;
        }*/
        if (dp_memo[i][j] != 100) {
          if (j == w || dp_memo[i][j + 1] > dp_memo[i][j]) {
            int s = dp_memo[i][j];
            int t = dp1[x][j + 1][i][dp_memo[i][j]];
            while (t == 0 && s < 19) {
              s++;
              t = dp1[x][j + 1][i][s];
            }
            if (t != 0) {
              while (dp_memo[i][t] > s + 1) {
                dp_memo[i][t] = s + 1;
                t--;
              }
            }
          }
          if (i == h || dp_memo[i + 1][j] > dp_memo[i][j]) {
            int s = dp_memo[i][j];
            int t = dp2[i + 1][y][j][dp_memo[i][j]];
            while (t == 0 && s < 19) {
              s++;
              t = dp2[i + 1][y][j][s];
            }
            if (t != 0) {
              while (dp_memo[t][j] > s + 1) {
                dp_memo[t][j] = s + 1;
                t--;
              }
            }
          }
        }
      }
    }
    for (int i = x; i <= h; i++) {
      rep(k, 20) dp1[x][y][i][k] = 0;
    }
    for (int j = y; j <= w; j++) {
      rep(k, 20) dp2[x][y][j][k] = 0;
    }
    for (int i = x; i <= h; i++) {
      for (int j = w; j >= y; j--) {
        if (dp_memo[i][j] == 100)
          continue;
        if (dp1[x][y][i][dp_memo[i][j]] == 0)
          dp1[x][y][i][dp_memo[i][j]] = j;
      }
      rep(k, 19) dp1[x][y][i][k + 1] =
          max(dp1[x][y][i][k], dp1[x][y][i][k + 1]);
    }
    for (int j = y; j <= w; j++) {
      for (int i = h; i >= x; i--) {
        if (dp_memo[i][j] == 100)
          continue;
        if (dp2[x][y][j][dp_memo[i][j]] == 0)
          dp2[x][y][j][dp_memo[i][j]] = i;
      }
      rep(k, 19) dp2[x][y][j][k + 1] =
          max(dp2[x][y][j][k], dp2[x][y][j][k + 1]);
    }
  }

  /*rep(k,19){
          cout << dp1[h][w][h][k] << endl;
  }*/

  rep(k, 19) {
    // cout << dp1[1][1][h][k] << endl;
    if (dp1[1][1][h][k] == w) {
      cout << k << endl;
      return 0;
    }
  }
}