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

#include <algorithm>
#include <functional>
#include <iostream>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define rep(i, n) for (int i = 0; i < n; i++)
#define all(a) a.begin(), a.end()

string dp[11][1 << 11];

int main() {
  int n;
  while (cin >> n && n) {
    vector<string> s(n);
    rep(i, n) { cin >> s[i]; }
    set<int, greater<int>> del;
    rep(i, n) for (int j = i + 1; j < n; j++) {
      if (s[i] == s[j]) {
        del.insert(j);
      }
    }
    for (auto i : del) {
      s.erase(s.begin() + i);
    }
    n = s.size();
    del.clear();
    rep(i, n) rep(j, n) if (i != j) {
      rep(k, s[i].size()) {
        if (s[i].substr(k, s[j].size()) == s[j]) {
          del.insert(j);
          break;
        }
      }
    }
    for (auto i : del) {
      s.erase(s.begin() + i);
    }
    n = s.size();
    int table[11][11];
    rep(i, n) rep(j, n) if (i != j) {
      table[i][j] = 0;
      rep(k, s[i].size()) {
        int len = min(s[j].size(), s[i].size() - k);
        if (s[i].substr(k) == s[j].substr(0, len)) {
          table[i][j] = max(table[i][j], len);
        }
      }
    }
    rep(bit, 1 << n) {
      rep(i, n) { dp[i][bit] = ""; }
    }
    rep(i, n) { dp[i][1 << i] = s[i]; }
    pair<size_t, string> ans = make_pair(1e9, "");
    rep(bit, 1 << n) {
      rep(i, n) if (dp[i][bit].size()) {
        if (bit == (1 << n) - 1) {
          ans = min(ans, make_pair(dp[i][bit].size(), dp[i][bit]));
        }
        rep(j, n) {
          if ((bit & (1 << j)) == 0) {
            string next = dp[i][bit] + s[j].substr(table[i][j]);
            if (dp[j][bit | (1 << j)].size() == 0 ||
                make_pair(next.size(), next) <
                    make_pair(dp[j][bit | (1 << j)].size(),
                              dp[j][bit | (1 << j)])) {
              dp[j][bit | (1 << j)] = next;
            }
          }
        }
      }
    }
    cout << ans.second << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
const int INF = 1e9;

int main() {
  int n;

  unordered_map<string, unordered_map<string, string>> table;
  while (cin >> n && n) {
    vector<string> s(n);
    rep(i, n) { cin >> s[i]; }
    rep(i, n) rep(j, n) if (i != j) {
      string res;
      bool work = false;
      rep(k, s[i].size()) {
        bool ok = true;
        rep(l, s[j].size()) {
          if (s[i].size() == k + l)
            break;
          if (s[i][k + l] != s[j][l]) {
            ok = false;
          }
        }
        if (ok) {
          res = s[i].substr(0, k) + s[j] +
                (s[i].size() > k + s[j].size() ? s[i].substr(k + s[j].size())
                                               : "");
          work = true;
          break;
        }
      }
      if (work == false) {
        res = s[i] + s[j];
      }
      table[s[i]][s[j]] = res.substr(s[i].size());
    }

    sort(s.begin(), s.end());
    pair<size_t, string> ans = make_pair(INF, "");
    do {
      string res = s[0];
      bool ok = true;
      for (int i = 1; i < n; i++) {
        res += table[s[i - 1]][s[i]];
        if (res.size() > ans.first) {
          ok = false;
          break;
        }
      }
      if (ok) {
        ans = min(ans, make_pair(res.size(), res));
      }
    } while (next_permutation(s.begin(), s.end()));
    cout << ans.second << endl;
  }
  return 0;
}