Problem p01650 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

int H, W, C;
int INF = 1e8;

vector<int> Gy, Gx;
char t[60][60];
int dp[50][50][50][50];

int dfs(int ay, int ax, int by, int bx) {
  if (ay < 0 || ax < 0 || by < 0 || bx < 0)
    return -INF;
  if (ay >= H || ax >= W || by >= H || bx >= W)
    return -INF;
  if (by < ay || bx < ax)
    return -INF;
  if (t[ay][ax] == '#' || t[by][bx] == '#')
    return -INF;
  if (ay == by && ax == bx)
    return 0;

  if (dp[ay][ax][by][bx] != -1)
    return dp[ay][ax][by][bx];
  int res = -INF;

  if ('a' <= t[ay][ax] && t[ay][ax] <= 'z' &&
      t[ay][ax] - 'a' + 'A' == t[by][bx]) {
    if ((by - ay) + (bx - ax) == 1)
      res = max(res, 1);
    res = max(res, dfs(ay + 1, ax, by - 1, bx) + 1);
    res = max(res, dfs(ay + 1, ax, by, bx - 1) + 1);
    res = max(res, dfs(ay, ax + 1, by - 1, bx) + 1);
    res = max(res, dfs(ay, ax + 1, by, bx - 1) + 1);
  }

  res = max(res, dfs(ay + 1, ax, by, bx));
  res = max(res, dfs(ay, ax + 1, by, bx));

  for (int i = 0; i < (int)Gy.size(); i++) {
    int y = Gy[i], x = Gx[i];
    if (y == ay && x == ax)
      continue;
    if (y == by && x == bx)
      continue;

    if (ay <= y && y <= by)
      if (ax <= x && x <= bx)
        res = max(res, dfs(ay, ax, y, x) + dfs(y, x, by, bx));
  }

  return dp[ay][ax][by][bx] = res;
}

int main() {
  while (1) {
    cin >> H >> W;
    if (H == 0 && W == 0)
      break;
    Gy.clear();
    Gx.clear();
    memset(dp, -1, sizeof(dp));
    for (int i = 0; i < H; i++) {
      scanf("%s", t[i]);
      for (int j = 0; j < W; j++) {
        if ('A' <= t[i][j] && t[i][j] <= 'Z') {
          Gy.push_back(i);
          Gx.push_back(j);
        }
      }
    }
    cout << max(-1, dfs(0, 0, H - 1, W - 1)) << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

int H, W, C;
char s[100], a[10000];
char t[100][100];
int id[100][100];
int INF = 1e8;
map<string, int> dp[100][100];
int ans;

int dfs(int y, int x, string s) {
  if (y < 0 || x < 0 || y >= H || x >= W || t[y][x] == '#')
    return -INF;
  if ('a' <= t[y][x] && t[y][x] <= 'z')
    s += t[y][x];
  // cout<<y<<' '<<x<<' '<<s<<endl;
  if (dp[y][x].count(s))
    return dp[y][x][s];

  int flg = 0;
  string ns = "";
  if ('A' <= t[y][x] && t[y][x] <= 'Z') {
    int k = -1;
    for (int i = 0; i < (int)s.size(); i++) {
      if (s[i] - 'a' + 'A' == t[y][x])
        k = i;
    }
    for (int i = 0; i < k; i++)
      ns += s[i];
    if (k != -1)
      flg = 1;
    else
      ns = s;
  } else
    ns = s;

  if (y == H - 1 && x == W - 1) {
    ans = 1;
    return flg;
  }

  int res = -INF; // max( dfs(y+1,x,s) , dfs(y,x+1,s) );
  res = max(res, dfs(y + 1, x, ns) + flg);
  res = max(res, dfs(y, x + 1, ns) + flg);

  return dp[y][x][s] = res;
}

int main() {
  while (1) {
    cin >> H >> W;
    if (H == 0 && W == 0)
      break;
    for (int i = 0; i < H; i++)
      for (int j = 0; j < W; j++)
        dp[i][j].clear();

    for (int i = 0; i < H; i++) {
      scanf("%s", s);
      for (int j = 0; j < W; j++) {
        t[i][j] = s[j];
      }
    }

    ans = 0;
    int out = dfs(0, 0, "");
    if (ans) {
      cout << out << endl;
    } else {
      cout << -1 << endl;
    }
  }
  return 0;
}