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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> P1;
typedef pair<P, P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i, x) for (int i = 0; i < x; i++)
#define SORT(x) sort(x.begin(), x.end())
#define ERASE(x) x.erase(unique(x.begin(), x.end()), x.end())
#define POSL(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin())
#define POSU(x, v) (upper_bound(x.begin(), x.end(), v) - x.begin())
#define mod 1000000007
int n;
string s[55];
ll dp[55][55][25];
bool u[55][55][25];
int nm[55][55][25];
ll rec(int L, int R, int num) {
  if (u[L][R][num])
    return dp[L][R][num];
  u[L][R][num] = 1;
  if (L == R) {
    dp[L][R][num] = 1;
    for (int j = num - 1; j < s[L].size(); j++)
      if (s[L][j] == '?')
        dp[L][R][num] = (dp[L][R][num] * 26LL) % mod;
    return dp[L][R][num];
  }
  int cnt = 0;
  for (int i = L; i <= R; i++) {
    if (s[i].size() < num) {
      if (i != L || cnt)
        return dp[L][R][num] = 0;
      cnt++;
    }
  }
  if (cnt) {
    if (cnt == R - L + 1) {
      return dp[L][R][num] = 1;
    } else
      return dp[L][R][num] = rec(L + cnt, R, num);
  }
  ll t[55][30] = {};
  t[L - 1][0] = 1;
  for (int i = L; i <= R; i++) {
    for (int j = L - 1; j < i; j++) {
      if (nm[j + 1][i][num] > 0) {
        // dp[j+1][i][num+1] wo kentou
        int k = nm[j + 1][i][num];
        {
          {
            ll R = rec(j + 1, i, num + 1);
            for (int l = 0; l < k; l++)
              t[i][k] = (t[i][k] + t[j][l] * R % mod) % mod;
          }
        }
      } else if (nm[j + 1][i][num] == 0) {
        ll R = rec(j + 1, i, num + 1);
        ll T = 0;
        for (int k = 1; k <= 26; k++) {
          T = (T + t[j][k - 1]) % mod;
          t[i][k] = (t[i][k] + T * R % mod) % mod;
        }
      }
    }
  }
  for (int i = 1; i <= 26; i++)
    dp[L][R][num] = (dp[L][R][num] + t[R][i]) % mod;
  return dp[L][R][num];
}
int main() {
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> s[i];
  for (int i = 1; i <= n; i++) {
    for (int j = i; j <= n; j++) {
      for (int k = 1; k <= 20; k++) {
        for (int x = i; x <= j; x++) {
          if (s[x].size() >= k) {
            if (s[x][k - 1] != '?') {
              if (nm[i][j][k] == 0)
                nm[i][j][k] = 1 + (s[x][k - 1] - 'a');
              else if (nm[i][j][k] != 1 + (s[x][k - 1] - 'a'))
                nm[i][j][k] = -1;
            }
          }
        }
      }
    }
  }
  cout << rec(1, n, 1) << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> P1;
typedef pair<P, P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i, x) for (int i = 0; i < x; i++)
#define SORT(x) sort(x.begin(), x.end())
#define ERASE(x) x.erase(unique(x.begin(), x.end()), x.end())
#define POSL(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin())
#define POSU(x, v) (upper_bound(x.begin(), x.end(), v) - x.begin())
#define mod 1000000007
int n;
string s[55];
ll dp[55][55][25];
bool u[55][55][25];
int nm[55][55][25];
ll rec(int L, int R, int num) {
  if (u[L][R][num])
    return dp[L][R][num];
  u[L][R][num] = 1;
  if (L == R) {
    dp[L][R][num] = 1;
    for (int j = num - 1; j < s[L].size(); j++)
      if (s[L][j] == '?')
        dp[L][R][num] = (dp[L][R][num] * 26LL) % mod;
    return dp[L][R][num];
  }
  int cnt = 0;
  for (int i = L; i <= R; i++) {
    if (s[i].size() < num) {
      if (i != L || cnt)
        return dp[L][R][num] = 0;
      cnt++;
    }
  }
  if (cnt) {
    if (cnt == R - L + 1) {
      return dp[L][R][num] = 1;
    } else
      return dp[L][R][num] = rec(L + cnt, R, num);
  }
  ll t[55][30] = {};
  t[L - 1][0] = 1;
  for (int i = L; i <= R; i++) {
    for (int j = L - 1; j < i; j++) {
      if (nm[j + 1][i][num] >= 0) {
        // dp[j+1][i][num+1] wo kentou
        for (int k = 1; k <= 26; k++) {
          if (nm[j + 1][i][num] == 0 || nm[j + 1][i][num] == k) {
            for (int l = 0; l < k; l++)
              t[i][k] =
                  (t[i][k] + t[j][l] * rec(j + 1, i, num + 1) % mod) % mod;
          }
        }
      }
    }
  }
  for (int i = 1; i <= 26; i++)
    dp[L][R][num] = (dp[L][R][num] + t[R][i]) % mod;
  return dp[L][R][num];
}
int main() {
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> s[i];
  for (int i = 1; i <= n; i++) {
    for (int j = i; j <= n; j++) {
      for (int k = 1; k <= 20; k++) {
        for (int x = i; x <= j; x++) {
          if (s[x].size() >= k) {
            if (s[x][k - 1] != '?') {
              if (nm[i][j][k] == 0)
                nm[i][j][k] = 1 + (s[x][k - 1] - 'a');
              else if (nm[i][j][k] != 1 + (s[x][k - 1] - 'a'))
                nm[i][j][k] = -1;
            }
          }
        }
      }
    }
  }
  cout << rec(1, n, 1) << endl;
}