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

#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// #define int ll
// #define endl "\\n"
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template <class T> ostream &operator<<(ostream &os, vector<T> const &);
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : " ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T> ostream &operator<<(ostream &os, tuple<T...> const &t) {
  _ot<0>(os, t);
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  return os << "(" << p.first << ", " << p.second << ") ";
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  rep(i, v.size()) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}
template <class T> inline bool chmax(T &x, T const &y) {
  return x < y ? x = y, true : false;
}
template <class T> inline bool chmin(T &x, T const &y) {
  return x > y ? x = y, true : false;
}
#ifdef DEBUG
#define dump(...)                                                              \\
  (cerr << #__VA_ARGS__ << " = " << mt(__VA_ARGS__) << " [" << __LINE__ << "]" \\
        << endl)
#else
#define dump(...)
#endif
// ll const mod = 1000000007;
ll const inf = 1 << 28;

bool comp(string const &s, string const &t) {
  return s.size() != t.size() ? s.size() < t.size() : s < t;
}

int N;
vvi g;

signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  while (cin >> N && N) {
    vector<string> s(N);
    rep(i, N) cin >> s[i];
    sort(all(s));
    s.erase(unique(all(s)), s.end());
    N = s.size();
    rep(i, N) rep(j, N) if (i != j) {
      if (s[i].find(s[j]) != string::npos) {
        s[j] = "~";
      }
    }
    s.erase(remove(all(s), "~"), s.end());
    N = s.size();
    g.assign(N, vi(N, inf));
    rep(i, N) rep(j, N) {
      if (i == j)
        continue;
      for (int k = min(s[i].size(), s[j].size()); k >= 0; k--) {
        string a(max(s[i].begin(), s[i].end() - k), s[i].end());
        string b(s[j].begin(), min(s[j].begin() + k, s[j].end()));
        if (a == b) {
          g[i][j] = k;
          break;
        }
      }
    }

    vector<pair<int, vector<char>>> cand;
    vector<char> k(N);
    rep(i, N) k[i] = i;
    int m = inf;
    do {
      int l = s[k[0]].size();
      rep(i, N - 1) { l += s[k[i + 1]].size() - g[k[i]][k[i + 1]]; }
      m = min(l, m);
      if (l <= m)
        cand.eb(l, k);
    } while (next_permutation(all(k)));
    sort(all(cand),
         [](const pair<int, vector<char>> &a,
            const pair<int, vector<char>> &b) { return a.first < b.first; });
    string ans(1000, '~');
    dump(cand.size());
    rep(i, cand.size()) { dump(cand[i]); }
    rep(i, cand.size()) {
      if (i != 0 && cand[i - 1].first < cand[i - 1].first)
        break;
      vector<char> &l = cand[i].second;
      string c = s[l[0]];
      rep(j, N - 1) { c += s[l[j + 1]].substr(g[l[j]][l[j + 1]]); }
      ans = min(ans, c, comp);
    }
    cout << ans << endl;
  }
}

Error: MLE

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// #define int ll
// #define endl "\\n"
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template <class T> ostream &operator<<(ostream &os, vector<T> const &);
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : " ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T> ostream &operator<<(ostream &os, tuple<T...> const &t) {
  _ot<0>(os, t);
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  return os << "(" << p.first << ", " << p.second << ") ";
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  rep(i, v.size()) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}
template <class T> inline bool chmax(T &x, T const &y) {
  return x < y ? x = y, true : false;
}
template <class T> inline bool chmin(T &x, T const &y) {
  return x > y ? x = y, true : false;
}
#ifdef DEBUG
#define dump(...)                                                              \\
  (cerr << #__VA_ARGS__ << " = " << mt(__VA_ARGS__) << " [" << __LINE__ << "]" \\
        << endl)
#else
#define dump(...)
#endif
// ll const mod = 1000000007;
ll const inf = 1 << 28;

bool comp(string const &s, string const &t) {
  return s.size() != t.size() ? s.size() < t.size() : s < t;
}

int N;
vvi g;

signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  while (cin >> N && N) {
    vector<string> s(N);
    rep(i, N) cin >> s[i];
    sort(all(s));
    s.erase(unique(all(s)), s.end());
    N = s.size();
    rep(i, N) rep(j, N) if (i != j) {
      if (s[i].find(s[j]) != string::npos) {
        s[j] = "~";
      }
    }
    s.erase(remove(all(s), "~"), s.end());
    N = s.size();
    g.assign(N, vi(N, inf));
    rep(i, N) rep(j, N) {
      if (i == j)
        continue;
      for (int k = min(s[i].size(), s[j].size()); k >= 0; k--) {
        string a(max(s[i].begin(), s[i].end() - k), s[i].end());
        string b(s[j].begin(), min(s[j].begin() + k, s[j].end()));
        if (a == b) {
          g[i][j] = k;
          break;
        }
      }
    }

    vector<pair<int, vector<char>>> cand;
    vector<char> k(N);
    rep(i, N) k[i] = i;
    do {
      int l = s[k[0]].size();
      rep(i, N - 1) { l += s[k[i + 1]].size() - g[k[i]][k[i + 1]]; }
      cand.eb(l, k);
    } while (next_permutation(all(k)));
    sort(all(cand),
         [](const pair<int, vector<char>> &a,
            const pair<int, vector<char>> &b) { return a.first < b.first; });
    string ans(100000, '~');
    dump(cand.size());
    rep(i, cand.size()) { dump(cand[i]); }
    rep(i, cand.size() - 1) {
      if (i != 0 && cand[i - 1].first < cand[i - 1].first)
        break;
      vector<char> &l = cand[i].second;
      string c = s[l[0]];
      rep(j, N - 1) { c += s[l[j + 1]].substr(g[l[j]][l[j + 1]]); }
      ans = min(ans, c, comp);
    }
    cout << ans << endl;
  }
}