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

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a; i < b; i++)
#define rrep(i, a, b) for (int i = a; i >= b; i--)
#define INF INT_MAX / 2

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef vector<vs> vvs;

int main() {
  while (1) {
    int n;
    cin >> n;
    if (n == 0)
      return 0;

    set<string> str;
    rep(i, 0, n) {
      string s;
      cin >> s;
      str.insert(s);
    }

    set<string> delstr;
    for (string a : str)
      for (string b : str) {
        if (a == b)
          continue;
        if (a.find(b) != string::npos)
          delstr.insert(b);
      }

    for (string a : delstr)
      str.erase(a);

    vector<string> s(str.begin(), str.end());
    n = s.size();

    vvi dist(n, vi(n, 0));
    rep(i, 0, n) rep(j, 0, n) {
      string a = s[i];
      string b = s[j];

      rrep(len, min(a.length(), b.length()), 1) {
        bool ok = true;
        rep(i, 0, len) {
          if (a[a.length() - 1 - len + 1 + i] != b[i])
            ok = false;
        }
        if (ok) {
          dist[i][j] = len;
          break;
        }
      }
    }

    string infstr = "";
    rep(i, 0, 11) infstr += "zzzzzzzzzz";
    vvs dp(1 << n, vs(n + 1, infstr));
    dp[0][n] = "";
    rep(mask, 0, (1 << n) - 1) rep(i, 0, n + 1) {
      if (100 < dp[mask][i].length())
        continue;
      rep(j, 0, n) if ((mask & (1 << j)) == 0) {
        int ni = mask + (1 << j);
        if (i == n)
          dp[ni][j] = s[j];
        else {
          string nstr = dp[mask][i] + s[j].substr(dist[i][j]);
          if (nstr.length() < dp[ni][j].length())
            dp[ni][j] = nstr;
          else if (nstr.length() == dp[ni][j].length() && nstr < dp[ni][j])
            dp[ni][j] = nstr;
        }
      }
    }

    string ans = infstr;
    rep(i, 0, n) {
      string a = dp[(1 << n) - 1][i];
      if (a.length() < ans.length())
        ans = a;
      else if (a.length() == ans.length() && a < ans)
        ans = a;
    }
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a; i < b; i++)
#define rrep(i, a, b) for (int i = a; i >= b; i--)

vector<string> words;
int N;

string ans;

string makestr(string a, string b) {
  rrep(len, min(a.length(), b.length()), 1) {
    bool ok = true;
    rep(i, 0, len) if (a[a.length() - len + i] != b[i]) ok = false;
    if (ok)
      return a + b.substr(len);
  }

  return a + b;
}

void dfs(int depth, int mask, string str) {
  // cout << "[ " << str << " ]" << endl;

  if (ans.length() < str.length())
    return;

  if (depth == N) {
    if (str.length() < ans.length())
      ans = str;
    else if (str.length() == ans.length()) {
      if (str < ans)
        ans = str;
    }

    return;
  }

  rep(i, 0, N) {
    if (mask & (1 << i))
      continue;

    dfs(depth + 1, mask + (1 << i), makestr(str, words[i]));
  }
}

int main() {
  while (1) {
    cin >> N;
    if (N == 0)
      return 0;

    // cout << makestr("apple", "length") << endl;
    // return 0;

    words.clear();
    ans = "";
    rep(i, 0, 1000) ans += "a";

    rep(i, 0, N) {
      string s;
      cin >> s;
      words.push_back(s);
    }

    dfs(0, 0, "");

    cout << ans << endl;
  }
}