Problem p01650 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
// const int dx[] = { -1, 0, 0, 1 }, dy[] = { 0, -1, 1, 0 };
//[const int dx[] = { -1, -1, -1, 0, 0, 1, 1, 1 }, dy[] = { 0, -1, 1, -1, 1, 0,
//-1, 1 };
bool valid(int x, int y, int h, int w) {
  return (x >= 0 && y >= 0 && x < h && y < w);
}
int place(int x, int y, int w) { return w * x + y; }

int h, w;
vs fld;
bool edge[55][55][55][55];
int dp[55][55][55][55];

int is_pair(char c, char d) {
  if (islower(c) && isupper(d) && toupper(c) == d)
    return 1;
  return 0;
}

int solve(int top, int left, int bottom, int right) {
  if (top == bottom && left == right)
    return 0;
  if (left > right || top > bottom)
    return 0;
  if (!edge[top][left][bottom][right])
    return 0;
  if (!valid(top, left, h, w) || !valid(bottom, right, h, w))
    return 0;
  if (dp[top][left][bottom][right] >= 0)
    return dp[top][left][bottom][right];
  int res = 0;
  if (valid(top + 1, left, h, w) && fld[top + 1][left] != '#')
    chmax(res, solve(top + 1, left, bottom, right));
  if (valid(top, left + 1, h, w) && fld[top][left + 1] != '#')
    chmax(res, solve(top, left + 1, bottom, right));
  if (islower(fld[top][left])) {
    int match = is_pair(fld[top][left], fld[bottom][right]);
    if (match) {
      if (valid(top + 1, left, h, w) && fld[top + 1][left] != '#') {
        chmax(res, solve(top + 1, left, bottom, right - 1) + 1);
        chmax(res, solve(top + 1, left, bottom - 1, right) + 1);
      }
      if (valid(top, left + 1, h, w) && fld[top][left + 1] != '#') {
        chmax(res, solve(top, left + 1, bottom - 1, right) + 1);
        chmax(res, solve(top, left + 1, bottom, right - 1) + 1);
      }
    } else {
      FOR(i, top, bottom + 1) FOR(j, left, right + 1) {
        if (fld[i][j] != toupper(fld[top][left]) || !edge[top][left][i][j] ||
            !edge[i][j][bottom][right])
          continue;
        chmax(res, solve(top, left, i, j) + solve(i, j, bottom, right));
      }
    }
  }
  // cout << top << " " << left << " " << bottom << " " << right << endl;
  // cout << res << endl;
  return dp[top][left][bottom][right] = res;
}

int main() {
  while (cin >> h >> w, h) {
    MS(edge, false);
    MS(dp, -1);
    fld.resize(h);
    REP(i, h) cin >> fld[i];
    REP(i, h) REP(j, w) {
      if (fld[i][j] == '#')
        continue;
      queue<pii> que;
      que.emplace(i, j);
      while (!que.empty()) {
        int x = que.front().first, y = que.front().second;
        que.pop();
        if (!edge[i][j][x + 1][y] && valid(x + 1, y, h, w) &&
            fld[x + 1][y] != '#') {
          edge[i][j][x + 1][y] = true;
          que.emplace(x + 1, y);
        }
        if (!edge[i][j][x][y + 1] && valid(x, y + 1, h, w) &&
            fld[x][y + 1] != '#') {
          edge[i][j][x][y + 1] = true;
          que.emplace(x, y + 1);
        }
      }
    }
    if (!(h == 1 && w == 1) && !edge[0][0][h - 1][w - 1]) {
      puts("-1");
      continue;
    }
    // int a = is_pair(fld[0][0], fld[h - 1][w - 1]);
    cout << solve(0, 0, h - 1, w - 1) << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
// const int dx[] = { -1, 0, 0, 1 }, dy[] = { 0, -1, 1, 0 };
//[const int dx[] = { -1, -1, -1, 0, 0, 1, 1, 1 }, dy[] = { 0, -1, 1, -1, 1, 0,
//-1, 1 };
bool valid(int x, int y, int h, int w) {
  return (x >= 0 && y >= 0 && x < h && y < w);
}
int place(int x, int y, int w) { return w * x + y; }

int h, w;
vs fld;
bool edge[55][55][55][55];
int dp[55][55][55][55];

int is_pair(char c, char d) {
  if (islower(c) && isupper(d) && toupper(c) == d)
    return 1;
  return 0;
}

int solve(int top, int left, int bottom, int right) {
  if (top == bottom && left == right)
    return 0;
  if (!valid(top, left, h, w) || !valid(bottom, right, h, w))
    return 0;
  if (dp[top][left][bottom][right] >= 0)
    return dp[top][left][bottom][right];
  int res = max(solve(top + 1, left, bottom, right),
                solve(top, left + 1, bottom, right));
  if (islower(fld[top][left])) {
    int match = is_pair(fld[top][left], fld[bottom][right]);
    if (match) {
      res++;
    } else {
      FOR(i, top, bottom + 1) FOR(j, left, right + 1) {
        if (fld[i][j] != toupper(fld[top][left]) || !edge[top][left][i][j] ||
            !edge[i][j][bottom][right])
          continue;
        chmax(res, solve(top, left, i, j) + solve(i, j, bottom, right));
      }
    }
  }
  /*
  FOR(i, top, bottom+1)FOR(j, left, right+1)
  {
          if (!islower(fld[i][j]) || !edge[top][left][i][j] ||
  !edge[i][j][bottom][right]) continue; int c = fld[i][j] - 'a'; FOR(k, i,
  bottom+1)FOR(l, j, right+1)
          {
                  if (fld[k][l] != 'A' + c || !edge[i][j][k][l] ||
  !edge[i][j][bottom][right]) continue; chmax(res, tmp + solve(top, left, i, j)
  + solve(i, j, k, l) + solve(k, l, bottom, right));
          }
  }*/
  return dp[top][left][bottom][right] = res;
}

int main() {
  while (cin >> h >> w, h) {
    MS(edge, false);
    MS(dp, -1);
    fld.resize(h);
    REP(i, h) cin >> fld[i];
    REP(i, h) REP(j, w) {
      if (fld[i][j] == '#')
        continue;
      queue<pii> que;
      que.emplace(i, j);
      while (!que.empty()) {
        int x = que.front().first, y = que.front().second;
        que.pop();
        if (valid(x + 1, y, h, w) && fld[x + 1][y] != '#') {
          edge[i][j][x + 1][y] = true;
          que.emplace(x + 1, y);
        }
        if (valid(x, y + 1, h, w) && fld[x][y + 1] != '#') {
          edge[i][j][x][y + 1] = true;
          que.emplace(x, y + 1);
        }
      }
    }
    if (!edge[0][0][h - 1][w - 1]) {
      puts("-1");
      continue;
    }
    // int a = is_pair(fld[0][0], fld[h - 1][w - 1]);
    cout << solve(0, 0, h - 1, w - 1) << endl;
  }
  return 0;
}