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

#include <bits/stdc++.h>

using namespace std;

int H, W;
string S[52];
int dp[53][53][53][53];

int rec(int sy, int gy, int sx, int gx) {
  if (sy >= gy || sx >= gx)
    return (0);
  if (sy + 1 == gy && sx + 1 == gx)
    return (0);
  int &ret = dp[sy][gy][sx][gx];
  if (~ret)
    return (ret);
  if (S[sy][sx] == '#')
    return (0);
  if (sy + 1 < gy && S[sy + 1][sx] != '#')
    ret = max(ret, rec(sy + 1, gy, sx, gx));
  if (sx + 1 < gx && S[sy][sx + 1] != '#')
    ret = max(ret, rec(sy, gy, sx + 1, gx));
  if (S[sy][sx] == '.' || isupper(S[sy][sx]))
    return (ret);
  char c = toupper(S[sy][sx]);
  bool v1[53][53] = {{}}, v2[53][53];
  v1[gy - 1][gx - 1] = true;
  for (int i = gy - 1; i >= sy; i--) {
    for (int j = gx - 1; j >= sx; j--) {
      if (!v1[i][j])
        continue;
      if (i - 1 >= sy && S[i - 1][j] != '#')
        v1[i - 1][j] = true;
      if (j - 1 >= sx && S[i][j - 1] != '#')
        v1[i][j - 1] = true;
    }
  }
  for (int i = 0; i <= 1; i++) {
    const int sa = sy + i, sb = sx + 1 - i;
    if (sa >= gy || sb >= gx || S[sa][sb] == '#')
      continue;
    memset(v2, false, sizeof(v2));
    v2[sa][sb] = true;
    for (int j = sa; j < gy; j++) {
      for (int k = sb; k < gx; k++) {
        if (!v2[j][k])
          continue;
        if (j + 1 < gy && S[j + 1][k] != '#')
          v2[j + 1][k] = true;
        if (k + 1 < gx && S[j][k + 1] != '#')
          v2[j][k + 1] = true;
      }
    }
    for (int j = sy; j < gy; j++) {
      for (int k = sx; k < gx; k++) {
        if (j + 1 < gy && (j == sy && k == sx || v2[j][k]) &&
            c == S[j + 1][k]) {
          if (j + 1 == gy - 1 && k == gx - 1)
            ret = max(ret, rec(sa, j + 1, sb, k + 1) + 1);
          if (v1[j + 2][k])
            ret =
                max(ret, rec(sa, j + 1, sb, k + 1) + rec(j + 2, gy, k, gx) + 1);
          if (v1[j + 1][k + 1])
            ret = max(ret, rec(sa, j + 1, sb, k + 1) +
                               rec(j + 1, gy, k + 1, gx) + 1);
        }
        if (k + 1 < gx && (j == sy && k == sx || v2[j][k]) &&
            c == S[j][k + 1]) {
          if (j == gy - 1 && k + 1 == gx - 1)
            ret = max(ret, rec(sa, j + 1, sb, k + 1) + 1);
          if (v1[j][k + 2])
            ret =
                max(ret, rec(sa, j + 1, sb, k + 1) + rec(j, gy, k + 2, gx) + 1);
          if (v1[j + 1][k + 1])
            ret = max(ret, rec(sa, j + 1, sb, k + 1) +
                               rec(j + 1, gy, k + 1, gx) + 1);
        }
      }
    }
  }
  return (ret);
}

int main() {
  while (cin >> H >> W, H) {
    for (int i = 0; i < H; i++)
      cin >> S[i];
    memset(dp, -1, sizeof(dp));
    cout << rec(0, H, 0, W) << endl;
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

int H, W;
string S[52];
int dp[50][50][50][50];
bool latte[53][53][53][53], malta[53][53][53][53];

int rec(int sy, int gy, int sx, int gx) {
  if (sy >= gy || sx >= gx)
    return (0);
  if (sy + 1 == gy && sx + 1 == gx)
    return (0);
  int &ret = dp[sy][gy][sx][gx];
  if (~ret)
    return (ret);
  if (S[sy][sx] == '#')
    return (0);
  if (sy + 1 < gy && S[sy + 1][sx] != '#')
    ret = max(ret, rec(sy + 1, gy, sx, gx));
  if (sx + 1 < gx && S[sy][sx + 1] != '#')
    ret = max(ret, rec(sy, gy, sx + 1, gx));
  if (S[sy][sx] == '.' || isupper(S[sy][sx]))
    return (ret);
  char c = toupper(S[sy][sx]);
  latte[sy][sx][gy - 1][gx - 1] = true;
  for (int i = gy - 1; i >= sy; i--) {
    for (int j = gx - 1; j >= sx; j--) {
      if (!latte[sy][sx][i][j])
        continue;
      if (i - 1 >= sy && S[i - 1][j] != '#')
        latte[sy][sx][i - 1][j] = true;
      if (j - 1 >= sx && S[i][j - 1] != '#')
        latte[sy][sx][i][j - 1] = true;
    }
  }
  for (int i = 0; i <= 1; i++) {
    const int sa = sy + i, sb = sx + 1 - i;
    if (sa >= gy || sb >= gx || S[sa][sb] == '#')
      continue;
    memset(malta[sy][sx], false, sizeof(malta[sy][sx]));
    malta[sy][sx][sa][sb] = true;
    for (int j = sa; j < gy; j++) {
      for (int k = sb; k < gx; k++) {
        if (!malta[sy][sx][j][k])
          continue;
        if (j + 1 < gy && S[j + 1][k] != '#')
          malta[sy][sx][j + 1][k] = true;
        if (k + 1 < gx && S[j][k + 1] != '#')
          malta[sy][sx][j][k + 1] = true;
      }
    }
    for (int j = sy; j < gy; j++) {
      for (int k = sx; k < gx; k++) {
        if (j + 1 < gy && malta[sy][sx][j][k] && c == S[j + 1][k]) {
          if (j + 1 == gy - 1 && k == gx - 1)
            ret = max(ret, rec(sa, j + 1, sb, k + 1) + 1);
          if (latte[sy][sx][j + 2][k])
            ret =
                max(ret, rec(sa, j + 1, sb, k + 1) + rec(j + 2, gy, k, gx) + 1);
          if (latte[sy][sx][j + 1][k + 1])
            ret = max(ret, rec(sa, j + 1, sb, k + 1) +
                               rec(j + 1, gy, k + 1, gx) + 1);
        }
        if (k + 1 < gx && (j == sy && k == sx || malta[sy][sx][j][k]) &&
            c == S[j][k + 1]) {
          if (j == gy - 1 && k + 1 == gx - 1)
            ret = max(ret, rec(sa, j + 1, sb, k + 1) + 1);
          if (latte[sy][sx][j][k + 2])
            ret =
                max(ret, rec(sa, j + 1, sb, k + 1) + rec(j, gy, k + 2, gx) + 1);
          if (latte[sy][sx][j + 1][k + 1])
            ret = max(ret, rec(sa, j + 1, sb, k + 1) +
                               rec(j + 1, gy, k + 1, gx) + 1);
        }
      }
    }
  }
  return (ret);
}

int main() {
  while (cin >> H >> W, H) {
    for (int i = 0; i < H; i++)
      cin >> S[i];
    memset(latte, false, sizeof(latte));
    memset(malta, false, sizeof(malta));
    memset(dp, -1, sizeof(dp));
    cout << rec(0, H, 0, W) << endl;
  }
}