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

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
typedef long long ll;
typedef pair<int, int> pii;

const int INF = 1e7;

int dp[1 << 14][14];
int conn[14][14];

int main() {
  int n;
  while (cin >> n, n) {
    vector<string> ins(n);
    rep(i, n) { cin >> ins[i]; }

    vector<string> in;
    rep(i, n) {
      bool dup = false;
      rep(j, n) {
        if (i == j)
          continue;
        if (ins[j].find(ins[i]) != string::npos) {
          dup = true;
          break;
        }
      }
      if (!dup)
        in.push_back(ins[i]);
    }
    n = in.size();

    rep(i, n) {
      rep(j, n) {
        if (in[i].find(in[j]) != string::npos) {
          conn[i][j] = 0;
        } else {
          int t = min(in[i].length(), in[j].length()) - 1;
          while (t > 0 &&
                 in[i].substr(in[i].length() - t) != in[j].substr(0, t))
            t--;
          conn[i][j] = in[j].length() - t;
        }
      }
    }

    rep(i, (1 << n)) rep(j, n) dp[i][j] = INF;
    for (int i = 0; i < n; i++) {
      dp[1 << i][i] = in[i].length();
    }
    for (int i = 0; i < (1 << n); i++) {
      for (int x = 0; x < n; x++) {
        if (i & (1 << x)) {
          rep(j, n) {
            if ((i & (1 << j)) == 0) {
              int k = i | (1 << j);
              int st = dp[i][x] + conn[x][j];
              if (dp[k][j] == 0 || dp[k][j] > st) {
                dp[k][j] = st;
              }
            }
          }
        }
      }
    }

    int mini = INF;
    rep(i, n) { mini = min(mini, dp[(1 << n) - 1][i]); }
    cout << mini << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
typedef long long ll;
typedef pair<int, int> pii;

string dp[(1 << 14) + 1];

int main() {
  int n;
  while (cin >> n, n) {
    vector<string> in(n);
    rep(i, n) { cin >> in[i]; }
    rep(i, (1 << n) + 1) { dp[i] = ""; }
    for (int i = 0; i < n; i++) {
      dp[1 << i] = in[i];
    }
    for (int i = 0; i <= (1 << n); i++) {
      if (dp[i] != "") {
        rep(j, n) {
          if ((i & (1 << j)) == 0) {

            int k = i | (1 << j);
            if (in[j].find(dp[i]) != string::npos ||
                dp[i].find(in[j]) != string::npos) {
              string s = (in[j].length() < dp[i].length() ? dp[i] : in[j]);
              if (dp[k] == "" || dp[k].length() > s.length()) {
                dp[k] = s;
              }
            } else {
              int h = min(in[j].length(), dp[i].length());
              int t = h;
              while (h > 0 &&
                     in[j].substr(in[j].length() - h) != dp[i].substr(0, h))
                h--;
              string sh = in[j] + dp[i].substr(h);
              if (dp[k] == "" || dp[k].length() > sh.length()) {
                dp[k] = sh;
              }

              while (t > 0 &&
                     dp[i].substr(dp[i].length() - t) != in[j].substr(0, t))
                t--;
              string st = dp[i] + in[j].substr(t);
              if (dp[k] == "" || dp[k].length() > st.length()) {
                dp[k] = st;
              }
            }
          }
        }
      }
    }
    //		cout << dp[(1<<n)-1] << endl;
    cout << dp[(1 << n) - 1].length() << endl;
  }
  return 0;
}