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

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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

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

#define FF first
#define SS second
template <class S, class T> istream &operator>>(istream &is, pair<S, T> &p) {
  return is >> p.FF >> p.SS;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << p.FF << " " << p.SS;
}
template <class T> void maxi(T &x, T y) {
  if (x < y)
    x = y;
}
template <class T> void mini(T &x, T y) {
  if (x > y)
    x = y;
}

const double EPS = 1e-10;
const double PI = acos(-1.0);
const LL MOD = 1e9 + 7;
int sfx = 'a' - 1;

int N;
VS vs;
int dp[64][64][32][32];
LL solve(int b, int e, int p, int lb) {
  int &ret = dp[b][e][p][lb];
  if (~ret)
    return ret;
  if (b >= e)
    return ret = 1;

  if (lb == 27)
    return ret = 0;
  if (p == 20)
    return ret = (e - b == 1);

  ret = 0;
  LL res = solve(b, e, p, lb + 1);
  for (int i = b; i < e; ++i) {
    if (vs[i][p] != '?') {
      int c = vs[i][p] - sfx;
      if (c != lb)
        break;
    } else if (lb == 0)
      break;
    (res += solve(b, i + 1, p + 1, 0) * solve(i + 1, e, p, lb + 1) % MOD) %=
        MOD;
  }
  return ret = res;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  cin >> N;
  vs.resize(N);
  REP(i, N) {
    cin >> vs[i];
    vs[i] += string(20 - SZ(vs[i]), sfx);
  }

  fill((int *)dp, (int *)dp + 64 * 64 * 32 * 32, -1);
  cout << solve(0, N, 0, 0) << endl;

  return 0;
}

Error: MLE

Fixed submission:

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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

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

#define FF first
#define SS second
template <class S, class T> istream &operator>>(istream &is, pair<S, T> &p) {
  return is >> p.FF >> p.SS;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << p.FF << " " << p.SS;
}
template <class T> void maxi(T &x, T y) {
  if (x < y)
    x = y;
}
template <class T> void mini(T &x, T y) {
  if (x > y)
    x = y;
}

const double EPS = 1e-10;
const double PI = acos(-1.0);
const LL MOD = 1e9 + 7;

int N;
VS vs;
LL dp[51][51][21][27][27];
LL solve(int b, int e, int p, int lb, int ub) {
  LL &res = dp[b][e][p][lb][ub];
  if (res >= 0)
    return res;
  if (b == e)
    return res = 1;
  if (lb >= ub)
    return res = 0;
  if (b + 1 == e) {
    if (vs[b][p] == '?') {
      res = ub - lb;
    } else {
      int c = vs[b][p] - 'a';
      if (!(lb <= c && c < ub))
        return res = 0;
      res = 1;
    }
    for (int i = p + 1; i < SZ(vs[b]); ++i)
      if (vs[b][i] == '?')
        (res *= 26) %= MOD;
    return res;
  }

  res = 0;
  for (int i = b + 1; i <= e; ++i) {
    int c = -1;
    for (int j = b; j < i; ++j)
      if (SZ(vs[j]) <= p) {
        c = 27;
        break;
      } else if (vs[j][p] != '?') {
        int nc = vs[j][p] - 'a';
        if (c < 0)
          c = nc;
        else if (c != nc)
          c = 27;
      }
    if (c == 27)
      break;
    if (c != -1) {
      if (lb <= c && c < ub)
        (res += solve(b, i, p + 1, 0, 26) * solve(i, e, p, c + 1, ub) % MOD) %=
            MOD;
    } else {
      for (int c = lb; c < ub; ++c) {
        (res += solve(b, i, p + 1, 0, 26) * solve(i, e, p, c + 1, ub) % MOD) %=
            MOD;
      }
    }
  }
  return res;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  cin >> N;
  vs.resize(N);
  REP(i, N) cin >> vs[i];
  fill((LL *)dp, (LL *)dp + 51 * 51 * 21 * 27 * 27, -1);
  cout << solve(0, N, 0, 0, 26) << endl;

  return 0;
}