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

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toStr(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define REP(i, n) FOR(i, 0, (n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX / 10;

string merge(string a, string b) {
  if (a.find(b) != string::npos) {
    return a;
  }
  if (b.find(a) != string::npos) {
    return b;
  }

  string res = a + b;

  int al = a.length(), bl = b.length();
  FOR(i, 1, min(al, bl)) {
    string as = a.substr(al - i);
    string bs = b.substr(0, i);
    if (as == bs) {
      res = a + b.substr(i);
    }
  }

  return res;
}

string minstr(string a, string b) {
  int al = a.length(), bl = b.length();
  if (al < bl) {
    return a;
  } else if (al > bl) {
    return b;
  } else if (a < b) {
    return a;
  } else {
    return b;
  }
}

bool exist(int st, int i) { return st & (1 << i); }

int main() {
  int N;
  while (cin >> N, N) {
    vs str(N);
    REP(i, N) { cin >> str[i]; }

    vector<vs> dp(1 << N, vs(N, string('z', 101)));
    REP(i, 1 << N) {
      if (i == 0) {
        REP(j, N) { dp[1 << j][j] = str[j]; }
      } else {
        REP(j, N) {
          if (!exist(i, j)) {
            REP(k, N) {
              if (exist(i, k)) {
                dp[i | (1 << j)][j] =
                    minstr(dp[i | (1 << j)][j], merge(dp[i][k], str[j]));
              }
            }
          }
        }
      }
    }

    string ans('z', 101);
    REP(i, N) { ans = minstr(ans, dp[(1 << N) - 1][i]); }
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T> inline string toStr(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define REP(i, n) FOR(i, 0, (n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);
const int INF = INT_MAX / 10;

string merge(string a, string b) {
  string res = a + b;
  int al = a.length(), bl = b.length();
  FOR(i, 1, min(al, bl)) {
    string as = a.substr(al - i);
    string bs = b.substr(0, i);
    if (as == bs) {
      res = a + b.substr(i);
    }
  }

  return res;
}

int main() {
  int N;
  while (cin >> N, N) {
    vs str(N);
    vi seed(N);
    REP(i, N) {
      cin >> str[i];
      seed[i] = i;
    }

    string ans('a', 101);
    do {
      string tmp;
      REP(i, N) { tmp = merge(tmp, str[seed[i]]); }
      if (tmp.length() < ans.length()) {
        ans = tmp;
      } else if (tmp.length() == ans.length()) {
        if (tmp < ans) {
          ans = tmp;
        }
      }
    } while (next_permutation(ALL(seed)));

    cout << ans << endl;
  }

  return 0;
}