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

#include <bits/stdc++.h>
using namespace std;

string connect(string a, string b) {
  for (int i = 0; i < a.length(); i++) {
    if (a.substr(i) == b.substr(0, a.length() - i))
      return b.substr(a.length() - i);
  }
  return b;
}

bool minCost(string a, string b) {
  if (a.length() != b.length())
    return a.length() < b.length();
  return a < b;
}

string solve(vector<string> s, vector<vector<string>> tail) {
  int n = s.size();
  vector<vector<string>> dp(1 << n, vector<string>(n, string(101, 'z')));
  for (int i = 0; i < n; i++) {
    dp[(1 << i)][i] = s[i];
  }
  for (int i = 0; i < (1 << n); i++) {
    for (int j = 0; j < n; j++) {
      if ((i & (1 << j)) == 0)
        continue;
      int m = j;
      for (int k = 0; k < n; k++) {
        if ((i & (1 << k)) == 0 || j == k)
          continue;
        // std::cout << i << " " << j << " " << k << std::endl;
        // std::cout << tail[k][j] << std::endl;
        if (minCost(dp[i ^ (1 << j)][k] + tail[k][j],
                    dp[i ^ (1 << j)][m] + tail[m][j]))
          m = k;
      }
      if (minCost(dp[i ^ (1 << j)][m] + tail[m][j], dp[i][j]))
        dp[i][j] = dp[i ^ (1 << j)][m] + tail[m][j];
    }
  }
  string res = string(101, 'z');
  for (int i = 0; i < n; i++) {
    if (minCost(dp[(1 << n) - 1][i], res))
      res = dp[(1 << n) - 1][i];
  }
  // for (int i = 0; i < (1 << n); i++) {
  //   for (int j = 0; j < n; j++) {
  //     std::cout << "i:" << i << " j:" << j << " " << dp[i][j] << std::endl;
  //   }
  //   std::cout << std::endl;

  //}
  return res;
}
int main(int argc, char *argv[]) {
  int n;
  while (cin >> n, n) {
    vector<string> s(n), use;
    for (int i = 0; i < n; i++) {
      cin >> s[i];
    }
    sort(s.begin(), s.end());
    s.erase(unique(s.begin(), s.end()), s.end());
    vector<int> del(s.size(), 0);
    for (int i = 0; i < s.size(); i++) {
      for (int j = 0; j < s.size(); j++) {
        if (i == j)
          continue;
        if (s[i].find(s[j]) != string::npos)
          del[j] = 1;
      }
    }
    for (int i = 0; i < del.size(); i++) {
      if (del[i] == 0)
        use.push_back(s[i]);
    }
    n = use.size();
    vector<vector<string>> tail(n, vector<string>(n));
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        tail[i][j] = connect(use[i], use[j]);
      }
    }
    // for (int i = 0; i < n; i++) {
    //   for (int j = 0; j < n; j++) {
    //     std::cout << tail[i][j] << std::endl;
    //   }
    //   std::cout << std::endl;
    // }
    std::cout << solve(use, tail) << std::endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

int main(int argc, char *argv[]) {
  int n;
  while (cin >> n, n) {
    string s[n];
    for (int i = 0; i < n; i++) {
      cin >> s[i];
    }
    vector<int> perm(n);
    for (int i = 0; i < n; i++) {
      perm[i] = i;
    }
    string tmp = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
    do {
      string ans = s[perm[0]];
      for (int i = 1; i < n; i++) {
        bool flag = false;
        for (int j = 0; j < ans.length(); j++) {
          if (ans.substr(j, s[perm[i]].length()) == s[perm[i]]) {
            flag = true;
          }
        }
        if (flag)
          continue;
        int pos, bpos = 0, fpos = 0;
        for (int j = 1; j <= min(ans.length(), s[perm[i]].length()); j++) {
          if (ans.substr(ans.length() - j) == s[perm[i]].substr(0, j))
            bpos = j;
        }
        for (int j = 1; j <= min(ans.length(), s[perm[i]].length()); j++) {
          if (ans.substr(0, j) == s[perm[i]].substr(s[perm[i]].length() - j))
            fpos = j;
        }
        if (bpos > fpos) {
          ans += s[perm[i]].substr(bpos);
        } else {
          ans = s[perm[i]].substr(0, s[perm[i]].length() - fpos) + ans;
        }
      }
      tmp = min(tmp, ans);
    } while (next_permutation(perm.begin(), perm.end()));
    std::cout << tmp << std::endl;
  }

  return 0;
}