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

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

int N, K;
string S[20];
int nxt[20][6][20];
int idx[20][20];
int R;
int dp[1 << 16][16][6];

string PERM(string pre, int j) {
  while (j > 0) {
    next_permutation(all(pre));
    j--;
  }
  return pre;
}

string res;

int dfs(int T, int i, int j) {
  if (T == ((1 << N) - 1))
    return 1;
  if (dp[T][i][j] != -1)
    return dp[T][i][j];
  rep(ni, N) {
    if (((T >> ni) & 1) == 1)
      continue;
    if (nxt[i][j][ni] == -1)
      continue;
    if (dfs((T | (1 << ni)), ni, nxt[i][j][ni]) == 1) {
      string tmp;
      tmp += 'A' + ni;
      res = tmp + res;
      return dp[T][i][j] = 1;
    }
  }
  return dp[T][i][j] = 0;
}

int main() {
  cin >> N >> K;
  memset(idx, -1, sizeof(idx));
  memset(nxt, -1, sizeof(nxt));
  rep(i, N) {
    cin >> S[i];
    rep(j, S[i].size()) idx[i][S[i][j] - 'A'] = j;
  }
  R = 1;
  rep(i, N - K) R = R * (i + 1);

  rep(i, N) rep(j, R) {
    string crt = S[i];
    reverse(all(crt));
    string tmp;
    rep(k, N) if (idx[i][k] == -1) tmp += 'A' + k;
    sort(all(tmp));
    crt += PERM(tmp, j);

    rep(k, N) {
      if (k == i)
        continue;
      int pre = -100;
      bool ok = true;
      string rest;
      rep(l, N) {
        if (idx[k][crt[l] - 'A'] == -1) {
          rest += crt[l];
        } else {
          if (pre > idx[k][crt[l] - 'A'])
            ok = false;
          else
            pre = idx[k][crt[l] - 'A'];
        }
      }
      if (ok) {
        tmp = rest;
        sort(all(tmp));
        rep(nj, R) if (PERM(tmp, nj) == rest) nxt[i][j][k] = nj;
      }
    }
  }

  string ans = "ZZ";
  rep(i, N) {
    rep(j, R) {
      memset(dp, -1, sizeof(dp));
      res.clear();
      if (dfs(1 << i, i, j) == 1) {
        string tmp;
        tmp += 'A' + i;
        minch(ans, tmp + res);
      }
    }
  }

  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

int N, K;
string S[20];
int nxt[20][6][20];
int idx[20][20];
int R;
int dp[1 << 17][17][6];

string PERM(string pre, int j) {
  while (j > 0) {
    next_permutation(all(pre));
    j--;
  }
  return pre;
}

string res;

int dfs(int T, int i, int j) {
  if (T == ((1 << N) - 1))
    return 1;
  // if(dp[T][i][j]!=-1)return dp[T][i][j];
  rep(ni, N) {
    if (((T >> ni) & 1) == 1)
      continue;
    if (nxt[i][j][ni] == -1)
      continue;
    if (dfs((T | (1 << ni)), ni, nxt[i][j][ni]) == 1) {
      string tmp;
      tmp += 'A' + ni;
      res = tmp + res;
      return dp[T][i][j] = 1;
    }
  }
  return dp[T][i][j] = 0;
}

int main() {
  cin >> N >> K;
  memset(idx, -1, sizeof(idx));
  memset(nxt, -1, sizeof(nxt));
  rep(i, N) {
    cin >> S[i];
    rep(j, S[i].size()) idx[i][S[i][j] - 'A'] = j;
  }
  R = 1;
  rep(i, N - K) R = R * (i + 1);

  rep(i, N) rep(j, R) {
    string crt = S[i];
    reverse(all(crt));
    string tmp;
    rep(k, N) if (idx[i][k] == -1) tmp += 'A' + k;
    sort(all(tmp));
    crt += PERM(tmp, j);

    rep(k, N) {
      if (k == i)
        continue;
      int pre = -100;
      bool ok = true;
      string rest;
      rep(l, N) {
        if (idx[k][crt[l] - 'A'] == -1) {
          rest += crt[l];
        } else {
          if (pre > idx[k][crt[l] - 'A'])
            ok = false;
          else
            pre = idx[k][crt[l] - 'A'];
        }
      }
      if (ok) {
        tmp = rest;
        sort(all(tmp));
        rep(nj, R) if (PERM(tmp, nj) == rest) nxt[i][j][k] = nj;
      }
    }
  }

  memset(dp, -1, sizeof(dp));
  string ans = "ZZ";
  rep(i, N) {
    rep(j, R) {
      res.clear();
      if (dfs(1 << i, i, j) == 1) {
        string tmp;
        tmp += 'A' + i;
        minch(ans, tmp + res);
      }
    }
  }

  cout << ans << endl;
  return 0;
}