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

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
const int INF = 1e8;
using namespace std;

// i???????????????????????????
bool getBit(int num, int i) { return ((num & (1 << i)) != 0); }

// i?????????1?????????
int setBit(int num, int i) { return num | (1 << i); }

// i?????????0?????????
int clearBit(int num, int i) {
  int mask = ~(1 << i);
  return num & mask;
}

// i?????????v??§???????????????
int updateBit(int num, int i, int v) {
  int mask = ~(1 << i);
  return (num & mask) | (v << i);
}

int connect(string a, string b) {
  rep(i, a.size()) {
    string a_sub = a.substr(i, min(a.size() - i, b.size()));
    string b_sub = b.substr(0, a_sub.size());
    if (a_sub == b_sub) {
      return b.size() - b_sub.size();
    }
  }
  return b.size();
}

int main() {
  int n;
  while (cin >> n, n) {
    vector<string> in(n);
    rep(i, n) { cin >> in[i]; }

    vector<string> str;
    rep(i, n) {
      bool f = false;
      rep(j, n) {
        if (i == j)
          continue;
        if (string::npos != in[j].find(in[i])) {
          f = true;
        }
      }
      if (not f)
        str.emplace_back(in[i]);
    }

    int c[20][20];
    n = str.size();
    rep(i, n) {
      rep(j, n) {
        if (i == j)
          continue;
        c[i][j] = connect(str[i], str[j]);
      }
    }

    int dp[1 << 14][20];
    rep(i, 1 << 14) rep(j, 20) dp[i][j] = INF;
    rep(i, n) dp[setBit(0, i)][i] = str[i].size();
    // rep(i,1 << n){ rep(j,n){ cout << dp[i][j] << endl; } cout << endl; }

    rep(s, 1 << n) {
      rep(i, n) {
        if (not getBit(s, i))
          continue;
        rep(j, n) {
          if (getBit(s, j))
            continue;
          // cout << i << ' ' << j << endl;
          // show(c[i][j])
          dp[setBit(s, j)][j] = min(dp[setBit(s, j)][j], dp[s][i] + c[i][j]);
        }
      }
    }
    // rep(i,1 << n){ rep(j,n){ cout << dp[i][j] << endl; } cout << endl; }

    int ans = INF;
    rep(i, n) { ans = min(ans, dp[(1 << n) - 1][i]); }
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
// const int INF = 1e8;
using namespace std;

// i???????????????????????????
bool getBit(int num, int i) { return ((num & (1 << i)) != 0); }

// i?????????1?????????
int setBit(int num, int i) { return num | (1 << i); }

int n, N;
vector<string> str;
map<pair<int, int>, int> memo;

string connect(string a, string b) {
  range(i, max<int>(1, a.size() - b.size() + 1), a.size()) {
    string a_sub = a.substr(i, a.size() - i);
    string b_sub = b.substr(0, a_sub.size());
    if (a_sub == b_sub) {
      string b_back = b.substr(a_sub.size(), b.size() - a_sub.size());
      return a + b_back;
    }
  }
  return a + b;
}

int dfs(int s, int pre, string sub) {
  // show(sub)
  if (memo.count(make_pair(s, pre)))
    return memo[make_pair(s, pre)];
  if (s == (1 << N) - 1)
    return sub.size();

  int res = 1e8;
  rep(i, N) {
    // show(i)
    if (not getBit(s, i)) {
      if (pre == -1) {
        res = min(res, dfs(setBit(s, i), i, str[i]));
      } else {
        res = min(res, dfs(setBit(s, i), i, connect(sub, str[i])));
      }
    }
  }
  // show(res)
  return memo[make_pair(s, pre)] = res;
}

int main() {
  while (cin >> n, n) {
    str.clear();
    memo.clear();

    vector<string> in(n);
    rep(i, n) { cin >> in[i]; }
    sort(all(in),
         [](const string &a, const string &b) { return a.size() < b.size(); });

    rep(i, n) {
      bool f = false;
      range(j, i + 1, n) {
        if (string::npos == in[j].find(in[i]))
          continue;
        f = true;
        break;
      }
      if (not f)
        str.emplace_back(in[i]);
    }
    // for(auto i : str){ show(i) }
    N = str.size();
    cout << dfs(0, -1, "") << endl;
  }
}