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

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcount

#define INF 10000000
#define mod 1000000007

int n;
string s[22];
bool cov[22];
int len[22][22];
int dp[1 << 15][15];

int main() {
  while (1) {
    cin >> n;
    if (n == 0)
      break;
    rep(i, n) cin >> s[i];
    vector<string> ss;
    memset(cov, 0, sizeof(cov));
    rep(i, n) rep(j, n) {
      if (i == j)
        continue;
      for (int k = 0; k + s[j].size() - 1 < s[i].size(); k++) {
        if (s[i].substr(k, s[j].size()) == s[j])
          cov[j] = true;
      }
    }
    rep(i, n) if (!cov[i]) ss.push_back(s[i]);
    n = ss.size();
    rep(i, n) rep(j, n) len[i][j] = INF;
    rep(i, n) rep(j, n) {
      if (i == j)
        continue;
      len[i][j] = ss[j].size();
      repl(k, 1, min(ss[i].size(), ss[j].size()) + 1) {
        if (ss[i].substr(ss[i].size() - k, k) == ss[j].substr(0, k))
          minch(len[i][j], ss[j].size() - k);
      }
    }
    rep(S, 1 << n) rep(i, n) dp[S][i] = INF;
    rep(i, n) dp[1 << i][i] = ss[i].size();
    rep(S, 1 << n) rep(i, n) {
      if (dp[S][i] == INF)
        continue;
      rep(j, n) {
        if ((S >> j) & 1)
          continue;
        minch(dp[S | (1 << j)][j], dp[S][i] + len[i][j]);
      }
    }
    int res = INF;
    rep(i, n) minch(res, dp[(1 << n) - 1][i]);
    cout << res << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

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

#define fi first
#define se second
#define repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define each(itr, v) for (auto itr : v)
#define pb(s) push_back(s)
#define mp(a, b) make_pair(a, b)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define maxch(x, y) x = max(x, y)
#define minch(x, y) x = min(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt(x) bitset<32>(x).count()

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<P, int> PPI;
typedef pair<ll, ll> PL;
typedef pair<P, ll> PPL;

#define INF INT_MAX / 3

#define MAX_N 1000

int n;
string s[20];
string dp[1 << 14];

string inf;

bool lesss(const string &a, const string &b) {
  if (a.length() == b.length())
    return a < b;
  else
    return a.length() < b.length();
}

string merge(string a, string b) {
  string resa = inf, resb = inf;
  rep(i, a.length()) {
    if (a.substr(i, min(a.length() - i, b.length())) ==
        b.substr(0, min(a.length() - i, b.length()))) {
      if (a.length() - i >= b.length())
        resa = a;
      else
        resa = a.substr(0, i) + b;
      break;
    }
  }

  rep(i, b.length()) {
    if (b.substr(i, min(b.length() - i, a.length())) ==
        a.substr(0, min(b.length() - i, a.length()))) {
      if (b.length() - i >= a.length())
        resb = b;
      else
        resb = b.substr(0, i) + a;
      break;
    }
  }
  if (resa == inf && resb == inf) {
    if (lesss(a + b, b + a))
      return a + b;
    else
      return b + a;
  } else {
    if (lesss(resa, resb))
      return resa;
    else
      return resb;
  }
}

int main() {
  cin.sync_with_stdio(false);
  rep(i, 11111) inf += "z";
  while (1) {
    cin >> n;
    if (n == 0)
      break;
    rep(i, n) cin >> s[i];
    rep(i, 1 << n) {
      if (bcnt(i) == 1) {
        rep(j, n) {
          if ((i >> j) & 1)
            dp[i] = s[j];
        }
      } else
        dp[i] = inf;
    }
    rep(i, 1 << n) {
      if (bcnt(i) == 0)
        continue;
      if (dp[i] == inf)
        continue;
      rep(j, n) {
        if ((i >> j) & 1)
          continue;
        string a = merge(dp[i], s[j]);
        if (lesss(a, dp[i | (1 << j)]))
          dp[i | (1 << j)] = a;
      }
    }
    cout << dp[(1 << n) - 1].length() << endl;
  }
  return 0;
}