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

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

using namespace std;

inline bool cmp(const string &a, const string &b) {
  if (a.size() == b.size())
    return a < b;
  return a.size() < b.size();
}

int main() {

  int N;
  while (cin >> N && N) {
    vector<string> vec(N);
    for (int i = 0; i < N; i++) {
      cin >> vec[i];
    }

    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
    N = vec.size();

    vector<bool> check(N, true);
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++) {
        if (i == j)
          continue;
        if (vec[i].find(vec[j]) != string::npos)
          check[j] = false;
      }

    vector<string> strs;
    for (int i = 0; i < N; i++) {
      if (check[i])
        strs.push_back(vec[i]);
    }

    N = strs.size();
    string next[12][12];
    for (int k = 0; k < N; k++) {
      for (int l = 0; l < N; l++) {
        if (k == l)
          continue;
        const string &s = strs[k], &t = strs[l];
        int const ssize = s.size(), tsize = t.size();
        next[k][l] = t;
        for (int i = 0; i < ssize; i++) {
          bool ok = true;
          for (int j = 0; j < ssize - i; j++) {
            if (j == tsize) {
              ok = false;
              break;
            }
            if (s[i + j] != t[j]) {
              ok = false;
              break;
            }
          }
          if (ok) {
            next[k][l] = t.substr(ssize - i);
            break;
          }
        }
      }
    }

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

    for (int i = 0; i < N; i++)
      dp[1 << i][i] = strs[i];

    for (int S = 0; S < (1 << N); S++) {
      for (int i = 0; i < N; i++) {
        if (!(S >> i & 1))
          continue;
        if (dp[S][i].empty())
          continue;
        for (int j = 0; j < N; j++) {
          if (S >> j & 1)
            continue;
          if (dp[S | (1 << j)][j].empty())
            dp[S | (1 << j)][j] = dp[S][i] + next[i][j];
          else
            dp[S | (1 << j)][j] =
                min(dp[S | (1 << j)][j], dp[S][i] + next[i][j], cmp);
        }
      }
    }

    string ans = dp[(1 << N) - 1][0];
    for (int i = 0; i < N; i++) {
      ans = min(ans, dp[(1 << N) - 1][i], cmp);
    }
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <tr1/unordered_map>

using namespace std;

int N;
int per[11];
string arr[11];
map<int, string> mp;
string nextstr[11][11];

inline bool cmp(const string &a, const string &b) {
  if (a.size() == b.size())
    return a < b;
  return a.size() < b.size();
}

string concat(string s, string t) {
  string ret = s + t;
  int const ssize = s.size();
  int const tsize = t.size();
  for (int i = 0; i < ssize; i++) {
    int ok = 0;
    for (int j = 0;; j++) {
      if (s[i + j] != t[j]) {
        ok = 0;
        break;
      }
      if (i + j + 1 == ssize) {
        ok = 1;
        break;
      }
      if (j + 1 == tsize) {
        ok = 2;
        break;
      }
    }
    if (ok == 1) {
      if (i)
        ret = min(ret, s.substr(0, i) + t, cmp);
      else
        ret = min(ret, t, cmp);
    }
    if (ok == 2) {
      ret = min(ret, s, cmp);
    }
  }
  return ret.substr(ssize);
}

string dfs(string &now, int S, int i) {

  string &ret = mp[S];

  if (i == N) {
    return ret = now;
  }

  string tmp;
  if (i)
    tmp = now + nextstr[per[i - 1]][per[i]];
  else
    tmp = arr[per[i]];
  tmp = dfs(tmp, S + (1 << per[i]), i + 1);
  if (ret.empty() || tmp.size() < ret.size()) {
    ret = tmp;
  }
  return ret;
}

int main() {

  while (cin >> N && N) {
    mp.clear();
    for (int i = 0; i < N; i++) {
      cin >> arr[i];
    }

    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        nextstr[i][j] = concat(arr[i], arr[j]);
        // cout << nextstr[i][j] << endl;
      }
    }

    for (int i = 0; i < N; i++)
      per[i] = i;

    string ret = string('*', 110);
    do {
      string s;
      ret = min(ret, dfs(s, 0, 0), cmp);
    } while (next_permutation(per, per + N));

    cout << ret << endl;
  }

  return 0;
}