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

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge {
  int u, v;
  ll w;
};

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

int foo(string &s, string &t) {
  int S = s.length(), T = t.length();
  for (int l = min(S, T); l >= 0; l--)
    if (s.substr(S - l) == t.substr(0, l))
      return T - l;
}

bool bar(string &s, string &t) {
  int S = s.length(), T = t.length();
  for (int i = 0; i + T <= S; i++)
    if (s.substr(i, T) == t)
      return true;
  return false;
}

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      break;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
      cin >> s[i];
    vector<bool> b(n, true);
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        if (j != i && b[j] && bar(s[j], s[i]))
          b[i] = false;
    vector<string> _s;
    for (int i = 0; i < n; i++)
      if (b[i])
        _s.push_back(s[i]);
    s = _s;
    n = s.size();
    vector<vector<int>> a(n, vector<int>(n));
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        a[i][j] = foo(s[i], s[j]);
    vector<vector<int>> dp(1 << n, vector<int>(n, INT_MAX));
    for (int S = 1; S < (1 << n); S++)
      for (int i = 0; i < n; i++) {
        if (S & (1 << i))
          ;
        else
          continue;
        int T = S - (1 << i);
        if (T == 0) {
          dp[S][i] = s[i].length();
          continue;
        }
        for (int j = 0; j < n; j++) {
          if (T & (1 << j))
            ;
          else
            continue;
          dp[S][i] = min(dp[S][i], dp[T][j] + a[j][i]);
        }
      }
    int mini = INT_MAX;
    for (int i = 0; i < n; i++)
      mini = min(mini, dp[(1 << n) - 1][i]);
    cout << mini << endl;
  }
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge {
  int u, v;
  ll w;
};

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

string foo(string &s, string &t) {
  int S = s.length(), T = t.length();
  for (int i = 0; i <= S; i++) {
    int l = min(S - i, T);
    if (s.substr(i, l) == t.substr(0, l))
      return s + t.substr(l);
  }
}

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      break;
    vector<string> s(n);
    for (int i = 0; i < n; i++)
      cin >> s[i];
    vector<vector<string>> dp(1 << n, vector<string>(n));
    for (int S = 1; S < (1 << n); S++)
      for (int i = 0; i < n; i++) {
        if (S & (1 << i))
          ;
        else
          continue;
        int T = S - (1 << i);
        if (T == 0) {
          dp[S][i] = s[i];
          continue;
        }
        for (int j = 0; j < n; j++) {
          if (T & (1 << j))
            ;
          else
            continue;
          string t = foo(dp[T][j], s[i]);
          if (dp[S][i].empty() || t.length() < dp[S][i].length())
            dp[S][i] = t;
        }
      }
    int mini = INT_MAX;
    for (int i = 0; i < n; i++)
      if (dp[(1 << n) - 1][i].length() < mini)
        mini = dp[(1 << n) - 1][i].length();
    cout << mini << endl;
  }
}