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

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int, int> pii;
#define REP(i, n) for (ll i = 0; i < n; ++i)
#define REPR(i, n) for (ll i = 1; i < n; ++i)
#define FOR(i, a, b) for (ll i = a; i < b; ++i)

#define DEBUG(x) cout << #x << ": " << x << endl
#define DEBUG_VEC(v)                                                           \\
  cout << #v << ":";                                                           \\
  REP(i, v.size()) cout << " " << v[i];                                        \\
  cout << endl
#define ALL(a) (a).begin(), (a).end()

#define MOD (ll)(1e9 + 7)
#define ADD(a, b) a = ((a) + (b)) % MOD
#define FIX(a) ((a) % MOD + MOD) % MOD

const int MAX = 14;

int n;
char buf[125];
string s[MAX];
string t[MAX];
bool alive[MAX];
// now, visited
string dp[MAX][1 << MAX];
int g[MAX][MAX];

int main() {
  while (true) {
    scanf("%d", &n);
    if (!n)
      break;
    REP(i, n) {
      scanf("%s", buf);
      s[i] = string(buf);
    }
    REP(i, n) alive[i] = true;
    REP(i, n) REP(j, n) {
      if (j == i)
        continue;
      if (s[i].size() > s[j].size())
        continue;
      int x = s[i].size();
      int y = s[j].size();
      FOR(k, 0, y - x + 1) {
        if (s[j].substr(k, x) == s[i]) {
          alive[i] = false;
          break;
        }
      }
    }
    int it = 0;
    REP(i, n) if (alive[i]) t[it++] = s[i];
    n = it;
    REP(i, n) s[i] = t[i];
    REP(i, n) REP(j, n) {
      string &ss = s[i];
      string &tt = s[j];
      int ovv = 0;
      int k = min(ss.size(), tt.size());
      FOR(x, 1, k + 1) {
        if (ss.substr(ss.size() - x) == tt.substr(0, x))
          ovv = x;
      }
      g[i][j] = ovv;
    }
    REP(i, n) REP(j, 1 << n) dp[i][j] = "#";
    dp[0][0] = "";
    REP(msk, (1 << n)) REP(i, n) {
      if (dp[i][msk] == "#")
        continue;
      string &ss = dp[i][msk];
      REP(to, n) {
        if ((msk >> to) & 1)
          continue;
        int nmsk = msk | (1 << to);
        if (msk == 0) {
          // not override
          dp[to][nmsk] = s[to];
        } else {
          int ovv = g[i][to];
          string nxt = ss + s[to].substr(ovv);
          if (dp[to][nmsk] == "#" || dp[to][nmsk].size() > nxt.size() ||
              (dp[to][nmsk].size() == nxt.size() && dp[to][nmsk] > nxt)) {
            dp[to][nmsk] = nxt;
          }
        }
      }
    }
    string ans = "#";
    REP(i, n) {
      string po = dp[i][(1 << n) - 1];
      if (ans == "#" || ans.size() > po.size() ||
          (ans.size() == po.size() && ans > po)) {
        ans = po;
      }
    }
    // printf("%s\\n", ans.c_str());
    printf("%d\\n", ans.size());
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int, int> pii;
#define REP(i, n) for (ll i = 0; i < n; ++i)
#define REPR(i, n) for (ll i = 1; i < n; ++i)
#define FOR(i, a, b) for (ll i = a; i < b; ++i)

#define DEBUG(x) cout << #x << ": " << x << endl
#define DEBUG_VEC(v)                                                           \\
  cout << #v << ":";                                                           \\
  REP(i, v.size()) cout << " " << v[i];                                        \\
  cout << endl
#define ALL(a) (a).begin(), (a).end()

#define MOD (ll)(1e9 + 7)
#define ADD(a, b) a = ((a) + (b)) % MOD
#define FIX(a) ((a) % MOD + MOD) % MOD

const int MAX = 14;

int n;
char buf[125];
string s[MAX];
string t[MAX];
bool alive[MAX];
// now, visited
string dp[MAX][1 << MAX];

int main() {
  while (true) {
    scanf("%d", &n);
    if (!n)
      break;
    REP(i, n) {
      scanf("%s", buf);
      s[i] = string(buf);
    }
    REP(i, n) alive[i] = true;
    REP(i, n) REP(j, n) {
      if (j == i)
        continue;
      if (s[i].size() > s[j].size())
        continue;
      int x = s[i].size();
      int y = s[j].size();
      FOR(k, 0, y - x + 1) {
        if (s[j].substr(k, x) == s[i]) {
          alive[i] = false;
          break;
        }
      }
    }
    int it = 0;
    REP(i, n) if (alive[i]) t[it++] = s[i];
    n = it;
    REP(i, n) s[i] = t[i];
    REP(i, n) REP(j, 1 << n) dp[i][j] = "#";
    dp[0][0] = "";
    REP(msk, (1 << n)) REP(i, n) {
      if (dp[i][msk] == "#")
        continue;
      string &ss = dp[i][msk];
      REP(to, n) {
        if ((msk >> to) & 1)
          continue;
        int nmsk = msk | (1 << to);
        if (msk == 0) {
          // not override
          dp[to][nmsk] = s[to];
        } else {
          int ovv = 0;
          int k = min(ss.size(), s[to].size());
          FOR(j, 1, k + 1) {
            if (ss.substr(ss.size() - j) == s[to].substr(0, j))
              ovv = j;
          }
          string nxt = ss + s[to].substr(ovv);
          if (dp[to][nmsk] == "#" || dp[to][nmsk].size() > nxt.size() ||
              (dp[to][nmsk].size() == nxt.size() && dp[to][nmsk] > nxt)) {
            dp[to][nmsk] = nxt;
          }
        }
      }
    }
    string ans = "#";
    REP(i, n) {
      string po = dp[i][(1 << n) - 1];
      if (ans == "#" || ans.size() > po.size() ||
          (ans.size() == po.size() && ans > po)) {
        ans = po;
      }
    }
    // printf("%s\\n", ans.c_str());
    printf("%d\\n", ans.size());
  }
  return 0;
}