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

#include <bits/stdc++.h>

#define REP(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;
const int INF = 1000000000;
int h, w;

int func(const vector<pair<int, int>> &v, int f, int t,
         const vector<vector<int>> &d, vector<vector<int>> &memo,
         bool fst = false) {
  if (memo[f][t] >= 0)
    return memo[f][t];
  int mxn = 0;
  vector<pair<int, int>> nv;
  for (auto p : v) {
    int fp, tp;
    tie(fp, tp) = p;
    if (d[f][fp] < INF && d[tp][t] < INF) {
      if (f == fp && !fst)
        continue;
      nv.push_back(p);
    }
  }
  for (auto p : nv) {
    int fp, tp;
    tie(fp, tp) = p;
    mxn = max(mxn, func(nv, fp, tp, d, memo) + func(nv, tp, t, d, memo) + 1);
  }
  return memo[f][t] = mxn;
}

int main() {
  while (1) {
    cin >> h >> w;
    if (!h)
      break;
    vector<string> m(h + 1, string(w + 1, '#'));
    REP(i, h) {
      string l;
      cin >> l;
      m[i] = l + "#";
    }
    int n = h * w;
    vector<vector<int>> d(n, vector<int>(n, INF));
    d[0][0] = 0;
    d[n - 1][n - 1] = 0;
    REP(i, h) REP(j, w) {
      int ind = i * w + j;
      if (m[i][j] != '#') {
        if (m[i + 1][j] != '#')
          d[ind][ind + w] = 1;
        if (m[i][j + 1] != '#')
          d[ind][ind + 1] = 1;
      }
    }
    REP(i, n) REP(j, n) {
      int ji = j / w, jj = j % w;
      if (ji > 0)
        d[i][j] = min(d[i][j], d[i][j - w] + d[j - w][j]);
      if (jj > 0)
        d[i][j] = min(d[i][j], d[i][j - 1] + d[j - 1][j]);
    }
    int diff = 'A' - 'a';
    vector<pair<int, int>> v;
    REP(i, n) REP(j, n) {
      int ii = i / w, ij = i % w;
      int ji = j / w, jj = j % w;
      if (m[ii][ij] < 'a' || 'z' < m[ii][ij])
        continue;
      if (d[i][j] < INF && m[ii][ij] + diff == m[ji][jj])
        v.emplace_back(i, j);
    }
    vector<vector<int>> memo(n, vector<int>(n, -1));
    if (d[0][n - 1] < INF)
      cout << func(v, 0, n - 1, d, memo, true) << endl;
    else
      cout << "-1" << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define REP(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;
const int INF = 1000000000;
int h, w;

int func(const vector<pair<int, int>> &v, int f, int t,
         const vector<vector<int>> &d, vector<vector<int>> &memo,
         bool fst = false) {
  if (memo[f][t] >= 0)
    return memo[f][t];
  int mxn = 0;
  for (auto p : v) {
    int fp, tp;
    tie(fp, tp) = p;
    if (d[f][fp] < INF && d[tp][t] < INF) {
      if ((f == fp || t == tp) && !fst)
        continue;
      mxn = max(mxn, func(v, fp, tp, d, memo) + func(v, tp, t, d, memo) + 1);
    }
  }
  return memo[f][t] = mxn;
}

int main() {
  while (1) {
    cin >> h >> w;
    if (!h)
      break;
    vector<string> m(h + 1, string(w + 1, '#'));
    REP(i, h) {
      string l;
      cin >> l;
      m[i] = l + "#";
    }
    int n = h * w;
    vector<vector<int>> d(n, vector<int>(n, INF));
    d[0][0] = 0;
    d[n - 1][n - 1] = 0;
    REP(i, h) REP(j, w) {
      int ind = i * w + j;
      if (m[i][j] != '#') {
        if (m[i + 1][j] != '#')
          d[ind][ind + w] = 1;
        if (m[i][j + 1] != '#')
          d[ind][ind + 1] = 1;
      }
    }
    REP(k, n) REP(i, n) REP(j, n) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
    int diff = 'A' - 'a';
    vector<pair<int, int>> v;
    REP(i, n) REP(j, n) {
      int ii = i / w, ij = i % w;
      int ji = j / w, jj = j % w;
      if (d[i][j] < INF && m[ii][ij] + diff == m[ji][jj])
        v.emplace_back(i, j);
    }
    vector<vector<int>> memo(n, vector<int>(n, -1));
    if (d[0][n - 1] < INF)
      cout << func(v, 0, n - 1, d, memo, true) << endl;
    else
      cout << "-1" << endl;
  }
  return 0;
}