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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1 << 29;

string min2(string a, string b) {
  if (a.empty())
    return b;
  if (a.size() > b.size())
    return b;
  if (a.size() == b.size() && a > b)
    return b;
  return a;
}

int main() {
  int n;
  while (cin >> n, n) {
    string s[n];
    REP(i, n) { cin >> s[i]; }

    string dp[1 << n][n];
    REP(i, n)
    dp[1 << i][i] = s[i];
    REP(S, 1 << n) {
      //      cout << bitset<5>(S) << endl;
      REP(i, n) if (S >> i & 1) {
        // cout << i << " ";
        // cout << dp[S][i] << endl;
        REP(j, n) if (!(S >> j & 1)) {
          string tmp = dp[S][i];
          if (tmp.find(s[j]) != tmp.npos) {
            dp[S | 1 << j][j] = min2(dp[S | 1 << j][j], dp[S][i]);
            continue;
          }
          bool f = 0;
          for (int k = min(s[j].size() - 1, tmp.size()); k >= 1;
               --k) { // tmp ツづ個前ツ陛サツつェツ暗ェツ致
            if (s[j].substr(s[j].size() - k, k) == tmp.substr(0, k)) {
              dp[S | 1 << j][j] = min2(dp[S | 1 << j][j],
                                       s[j].substr(0, s[j].size() - k) + tmp);
              f = 1;
              break;
            }
          }
          for (int k = min(s[j].size() - 1, tmp.size()); k >= 1;
               --k) { // tmp ツづ個古」ツ陛サツつェツ暗ェツ致
            if (s[j].substr(0, k) == tmp.substr(tmp.size() - k, k)) {
              dp[S | 1 << j][j] = min2(dp[S | 1 << j][j], tmp + s[j].substr(k));
              f = 1;
              break;
            }
          }
          if (!f) {
            dp[S | 1 << j][j] =
                min2(dp[S | 1 << j][j], min(tmp + s[j], s[j] + tmp));
          }
        }
      }
    }
    string res;

    REP(i, n)
    res = min2(res, dp[(1 << n) - 1][i]);
    cout << res << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1 << 29;

int main() {
  int n;
  while (cin >> n, n) {
    string s[n];
    REP(i, n) { cin >> s[i]; }

    set<string> v[1 << n];
    v[0].insert("");
    REP(S, 1 << n) {

      //      cout << bitset<4>(S) << endl;
      REP(i, n) {
        if (!(S >> i & 1)) {
          FOR(it, v[S]) {

            string tmp = *it;
            if (tmp.find(s[i]) != tmp.npos) {
              v[S | 1 << i].insert(tmp);
              continue;
            }
            bool f = 0;
            for (int j = min(s[i].size() - 1, tmp.size()); j >= 1;
                 --j) { // tmp ツづ個前ツ陛サツつェツ暗ェツ致
              if (s[i].substr(s[i].size() - j, j) == tmp.substr(0, j)) {
                v[S | 1 << i].insert(s[i].substr(0, s[i].size() - j) + tmp);
                f = 1;
                break;
              }
            }
            for (int j = min(s[i].size() - 1, tmp.size()); j >= 1;
                 --j) { // tmp ツづ個古」ツ陛サツつェツ暗ェツ致
              if (s[i].substr(0, j) == tmp.substr(tmp.size() - j, j)) {
                v[S | 1 << i].insert(tmp + s[i].substr(j));
                f = 1;
                break;
              }
            }
            if (!f) {
              v[S | 1 << i].insert(tmp + s[i]);
              v[S | 1 << i].insert(s[i] + tmp);
            }
          }
        }
      }
    }
    string res;
    int mi = INF;
    FOR(it, v[(1 << n) - 1]) {
      if (it->size() < mi) {
        res = *it;
        mi = res.size();
      } else if (it->size() == mi)
        res = min(res, *it);
    }
    cout << res << endl;
  }
}