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

#include <bits/stdc++.h>
#define N 14
#define S 21
#define INF (1e9)
using namespace std;

int n, cnt, memo[N][N], dp[(1 << N)][N], ans;
bool t[N];
string is[N], s[N];

bool check(string a, string b) {
  int alen = a.size(), blen = b.size();
  for (int i = 0; i <= blen - alen; i++)
    if (a == b.substr(i, alen))
      return true;
  return false;
}

int check2(string a, string b) {
  int alen = a.size(), blen = b.size();
  for (int i = blen - 1; i >= 1; i--) {
    if (alen - i < 0)
      continue;
    string s1 = a.substr(alen - i, i);
    string s2 = b.substr(0, i);
    if (s1 == s2)
      return blen - i;
  }
  return blen;
}

int main() {
  while (1) {
    cin >> n;
    if (!n)
      break;
    for (int i = 0; i < n; i++)
      cin >> is[i];
    memset(t, 0, sizeof(t));
    for (int i = 0; i < n; i++)
      for (int j = i + 1; j < n; j++) {
        int ilen = is[i].size();
        int jlen = is[j].size();
        if (ilen >= jlen && check(is[j], is[i]))
          t[j] = true;
        if (ilen < jlen && check(is[i], is[j]))
          t[i] = true;
      }
    cnt = 0;
    for (int i = 0; i < n; i++)
      if (!t[i])
        s[cnt] = is[i], cnt++;
    n = cnt;
    memset(memo, 0, sizeof(memo));
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++) {
        if (i == j)
          continue;
        memo[i][j] = check2(s[i], s[j]);
      }
    for (int i = 0; i < (1 << n); i++)
      for (int j = 0; j < n; j++)
        dp[i][j] = INF;
    for (int i = 0; i < n; i++)
      dp[(1 << i)][i] = s[i].size();
    for (int i = 0; i < (1 << n); i++)
      for (int j = 0; j < n; j++) {
        if (dp[i][j] == INF)
          continue;
        for (int k = 0; k < n; k++) {
          if (!(i & (1 << k)))
            dp[(i | (1 << k))][k] =
                min(dp[(i | (1 << k))][k], dp[i][j] + memo[j][k]);
        }
      }
    ans = INF;
    for (int i = 0; i < n; i++)
      ans = min(ans, dp[((1 << n) - 1)][i]);
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define N 15
#define INF (1e9)
using namespace std;

int n, cnt, memo[N][N], dp[(1 << N)][N], ans;
bool t[N];
string is[N], s[N];

int check(string s1, string s2) {
  int dq[N][N];
  int len1 = s1.size();
  int len2 = s2.size();
  memset(dq, 0, sizeof(dq));
  for (int i = 0; i < len1; i++)
    for (int j = 0; j < len2; j++) {
      if (s1[i] == s2[j])
        dq[i + 1][j + 1] = dq[i][j] + 1;
      else
        dq[i + 1][j + 1] = max(dq[i][j + 1], dq[i + 1][j]);
    }
  if (dq[len1][len2] == len1)
    return 1;
  if (dq[len1][len2] == len2)
    return 2;
  return 0;
}

int check2(string a, string b) {
  int alen = a.size(), blen = b.size();
  for (int i = blen - 1; i >= 1; i--) {
    if (alen - i < 0)
      continue;
    string s1 = a.substr(alen - i, i);
    string s2 = b.substr(0, i);
    if (s1 == s2)
      return blen - i;
  }
  return blen;
}

int main() {
  while (1) {
    cin >> n;
    if (!n)
      break;
    for (int i = 0; i < n; i++)
      cin >> is[i];
    memset(t, 0, sizeof(t));
    for (int i = 0; i < n; i++)
      for (int j = i + 1; j < n; j++) {
        int r = check(is[i], is[j]);
        if (!r)
          continue;
        if (r == 1)
          t[i] = true;
        if (r == 2)
          t[j] = true;
      }
    cnt = 0;
    for (int i = 0; i < n; i++)
      if (!t[i])
        s[cnt] = is[i], cnt++;
    n = cnt;
    memset(memo, 0, sizeof(memo));
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++) {
        if (i == j)
          continue;
        memo[i][j] = check2(s[i], s[j]);
      }
    for (int i = 0; i < (1 << n); i++)
      for (int j = 0; j < n; j++)
        dp[i][j] = INF;
    for (int i = 0; i < n; i++)
      dp[(1 << i)][i] = s[i].size();
    for (int i = 0; i < (1 << n); i++)
      for (int j = 0; j < n; j++) {
        if (dp[i][j] == INF)
          continue;
        for (int k = 0; k < n; k++) {
          if (!(i & (1 << k)))
            dp[(i | (1 << k))][k] =
                min(dp[(i | (1 << k))][k], dp[i][j] + memo[j][k]);
        }
      }
    ans = INF;
    for (int i = 0; i < n; i++)
      ans = min(ans, dp[((1 << n) - 1)][i]);
    cout << ans << endl;
  }
  return 0;
}