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

#include <bits/stdc++.h>
using namespace std;
int N, K;
string t[16];
string ans = "";
bool used[16];
int f[16];
int INF = 1e9 + 7;

bool check(int key) {
  vector<int> v;
  for (int i = 0; i < K; i++) {
    int id = t[key][i] - 'A';
    v.push_back(f[id]);
  }
  for (int i = 0; i + 1 < K; i++)
    if (v[i] > v[i + 1])
      return false;
  return true;
}

void update(int key) {
  for (int i = 0; i < K; i++) {
    int id = t[key][i] - 'A';
    f[id] = -100 - i;
  }
  vector<int> X;
  for (int i = 0; i < N; i++) {
    if (f[i] == INF)
      continue;
    X.push_back(f[i]);
  }
  sort(X.begin(), X.end());
  X.erase(unique(X.begin(), X.end()), X.end());
  for (int i = 0; i < N; i++) {
    if (f[i] == INF)
      continue;
    f[i] = lower_bound(X.begin(), X.end(), f[i]) - X.begin();
  }
}

typedef unsigned long long ull;

ull B = 1e9 + 9;
map<int, map<ull, bool>> mp;

bool dfs(int depth = 0) {
  int bit = 0;
  ull key = 0;
  for (int i = 0; i < N; i++) {
    if (used[i])
      bit += (1 << i);
    key *= B;
    if (f[i] == INF)
      key += 1999;
    else
      key += (f[i] + 1);
  }
  if (mp[bit][key])
    return false;
  mp[bit][key] = true;

  if (depth == N)
    return true;
  int tmp[16];
  for (int i = 0; i < N; i++)
    tmp[i] = f[i];

  for (int i = 0; i < N; i++) {
    if (used[i])
      continue;
    if (!check(i))
      continue;

    update(i);
    used[i] = true;

    if (dfs(depth + 1)) {
      ans.push_back('A' + i);
      return true;
    }

    used[i] = false;
    for (int j = 0; j < N; j++)
      f[j] = tmp[j];
  }
  return false;
}

int main() {
  cin >> N >> K;
  for (int i = 0; i < N; i++)
    cin >> t[i];
  fill(used, used + N, false);
  fill(f, f + N, INF);
  dfs();
  reverse(ans.begin(), ans.end());
  cout << ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
int N, K;
string t[16];
string ans = "";
bool used[16];
int f[16];
int INF = 1e8;

bool check(int key) {
  vector<int> v;
  for (int i = 0; i < K; i++) {
    int id = t[key][i] - 'A';
    v.push_back(f[id]);
  }
  for (int i = 0; i + 1 < K; i++)
    if (v[i] > v[i + 1])
      return false;
  return true;
}

void update(int key) {
  for (int i = 0; i < K; i++) {
    int id = t[key][i] - 'A';
    f[id] = -100 - i;
  }
  vector<int> X;
  for (int i = 0; i < N; i++) {
    if (f[i] == INF)
      continue;
    X.push_back(f[i]);
  }
  sort(X.begin(), X.end());
  X.erase(unique(X.begin(), X.end()), X.end());
  for (int i = 0; i < N; i++) {
    if (f[i] == INF)
      continue;
    f[i] = lower_bound(X.begin(), X.end(), f[i]) - X.begin();
  }
}

bool dfs(int depth = 0) {
  if (depth == N)
    return true;
  int tmp[16];
  for (int i = 0; i < N; i++)
    tmp[i] = f[i];

  for (int i = 0; i < N; i++) {
    if (used[i])
      continue;
    if (!check(i))
      continue;

    update(i);
    used[i] = true;

    if (dfs(depth + 1)) {
      ans.push_back('A' + i);
      return true;
    }

    used[i] = false;
    for (int j = 0; j < N; j++)
      f[j] = tmp[j];
  }
  return false;
}

int main() {
  cin >> N >> K;
  for (int i = 0; i < N; i++)
    cin >> t[i];
  fill(used, used + N, false);
  fill(f, f + N, INF);
  dfs();
  reverse(ans.begin(), ans.end());
  cout << ans << endl;
  return 0;
}