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

#include <iostream>
#include <queue>
#include <vector>

#define MAX_N 10
#define MAX_S 10

using namespace std;

string cat(const string &str1, const string &str2) {
  int L = min(str1.size(), str2.size());
  int l = 0, r = L;

  // ??????
  if (str1.size() < str2.size()) {
    for (int i = 0; i <= str2.size() - str1.size(); ++i) {
      bool f = true;
      for (int j = 0; j < str1.size(); ++j) {
        if (str2[i + j] != str1[j]) {
          f = false;
          break;
        }
      }
      if (f)
        return str2;
    }
  } else {
    for (int i = 0; i <= str1.size() - str2.size(); ++i) {
      bool f = true;
      for (int j = 0; j < str2.size(); ++j) {
        if (str1[i + j] != str2[j]) {
          f = false;
          break;
        }
      }
      if (f)
        return str1;
    }
  }

  // ??£???
  int cut = 0;
  for (int k = L - 1; k >= 1; --k) {
    bool f = true;
    for (int i = 0; i < k; ++i) {
      if (str1[str1.size() - k + i] != str2[i]) {
        f = false;
        break;
      }
    }
    if (f) {
      cut = k;
      break;
    }
  }
  return str1 + str2.substr(cut);
}

string dp[MAX_N][MAX_N][1 << MAX_N]; // dp[left][right][flag] = str
int main() {
  string INF = "";
  for (int i = 0; i < MAX_N + 1; ++i) {
    for (int j = 0; j < MAX_S; ++j) {
      INF += "W";
    }
  }

  int n;
  while (cin >> n, n) {
    vector<string> v;
    for (int i = 0; i < n; ++i) {
      string str;
      cin >> str;
      v.push_back(str);
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        for (int k = 0; k < (1 << MAX_N); ++k) {
          dp[i][j][k] = INF;
        }
      }
    }

    vector<vector<int>> Froms(n + 1);
    bool fFroms[MAX_N + 1][1 << MAX_N] = {0};
    fFroms[0][0] = true;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < (1 << n); ++j) {
        if (fFroms[i][j]) {
          for (int k = 0; k < n; ++k) {
            if (j & (1 << k))
              continue;
            fFroms[i + 1][j | (1 << k)] = true;
          }
        }
      }
    }
    for (int i = 0; i < n + 1; ++i) {
      for (int j = 0; j < (1 << n); ++j) {
        if (fFroms[i][j]) {
          Froms[i].push_back(j);
        }
      }
    }

    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j)
        dp[i][j][0] = "";
    for (int t = 0; t < n; ++t) {
      for (int fromL = 0; fromL < n; ++fromL)
        for (int fromR = 0; fromR < n; ++fromR) {
          for (int fid = 0; fid < Froms[t].size(); ++fid) {
            //				for (int state = 0; state < (1 << n); ++state)
            //{
            int state = Froms[t][fid];
            if (dp[fromL][fromR][state].size() == INF.size())
              continue;
            for (int to = 0; to < n; ++to) {
              if (state & (1 << to))
                continue;

              int next = state | (1 << to);
              string s1 = dp[fromL][fromR][state];
              string s2 = v[to];

              string left = cat(s2, s1);
              if (left.size() < dp[to][fromR][next].size() ||
                  (left.size() == dp[to][fromR][next].size() &&
                   left < dp[to][fromR][next])) {
                dp[to][fromR][next] = left;
              }

              string right = cat(s1, s2);
              if (right.size() < dp[fromL][to][next].size() ||
                  (right.size() == dp[fromL][to][next].size() &&
                   right < dp[fromL][to][next])) {
                dp[fromL][to][next] = right;
              }
              // cout << s1 << " " << s2 << " " << left << " " << right << endl;
            }
          }
        }
    }
    string ans = INF;
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j) {
        if (dp[i][j][(1 << n) - 1].size() < ans.size()) {
          ans = dp[i][j][(1 << n) - 1];
        } else if (dp[i][j][(1 << n) - 1].size() == ans.size() &&
                   dp[i][j][(1 << n) - 1] < ans) {
          ans = dp[i][j][(1 << n) - 1];
        }
      }
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <iostream>
#include <queue>
#include <vector>

#define MAX_N 10
#define MAX_S 10

using namespace std;

string cat(const string &str1, const string &str2) {
  int L = min(str1.size(), str2.size());
  int l = 0, r = L;

  // ??????
  if (str1.size() < str2.size()) {
    for (int i = 0; i <= str2.size() - str1.size(); ++i) {
      bool f = true;
      for (int j = 0; j < str1.size(); ++j) {
        if (str2[i] != str1[j]) {
          f = false;
          break;
        }
      }
      if (f)
        return str2;
    }
  } else {
    for (int i = 0; i <= str1.size() - str2.size(); ++i) {
      bool f = true;
      for (int j = 0; j < str2.size(); ++j) {
        if (str1[i] != str2[j]) {
          f = false;
          break;
        }
      }
      if (f)
        return str1;
    }
  }

  // ??£???
  int cut = 0;
  for (int k = L - 1; k >= 1; --k) {
    bool f = true;
    for (int i = 0; i < k; ++i) {
      if (str1[str1.size() - k + i] != str2[i]) {
        f = false;
        break;
      }
    }
    if (f) {
      cut = k;
      break;
    }
  }
  return str1 + str2.substr(cut);
}

string dp[MAX_N][MAX_N][1 << MAX_N]; // dp[left][right][flag] = str
int main() {
  string INF = "";
  for (int i = 0; i < MAX_N + 1; ++i) {
    for (int j = 0; j < MAX_S; ++j) {
      INF += "W";
    }
  }

  int n;
  while (cin >> n, n) {
    vector<string> v;
    for (int i = 0; i < n; ++i) {
      string str;
      cin >> str;
      v.push_back(str);
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        for (int k = 0; k < (1 << MAX_N); ++k) {
          dp[i][j][k] = INF;
        }
      }
    }

    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j)
        dp[i][j][0] = "";
    for (int t = 0; t < n; ++t) {
      for (int fromL = 0; fromL < n; ++fromL)
        for (int fromR = 0; fromR < n; ++fromR) {
          for (int state = 0; state < (1 << n); ++state) {
            if (dp[fromL][fromR][state].size() == INF.size())
              continue;
            for (int to = 0; to < n; ++to) {
              if (state & (1 << to))
                continue;

              int next = state | (1 << to);
              string s1 = dp[fromL][fromR][state];
              string s2 = v[to];

              string left = cat(s2, s1);
              if (left.size() < dp[to][fromR][next].size()) {
                dp[to][fromR][next] = left;
              }

              string right = cat(s1, s2);
              if (right.size() < dp[fromL][to][next].size()) {
                dp[fromL][to][next] = right;
              }
              // cout << s1 << " " << s2 << " " << left << " " << right << endl;
            }
          }
        }
    }
    string ans = INF;
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j) {
        if (dp[i][j][(1 << n) - 1].size() < ans.size()) {
          ans = dp[i][j][(1 << n) - 1];
        }
      }
    cout << ans << endl;
  }
}