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

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define all(c) (c).begin(), (c).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define pb(e) push_back(e)
#define mp(a, b) make_pair(a, b)
#define fr first
#define sc second

const int INF = 100000000;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
using namespace std;
typedef pair<int, int> P;
typedef long long ll;

int n;
string cties[20];
int G[20][20];

int dist(string s1, string s2) {
  int ret = 0;
  int m = min(s1.size(), s2.size());
  reverse(all(s1));
  rep(i, m) {
    string t = s1.substr(0, i);
    reverse(all(t));
    if (t == s2.substr(0, i))
      ret = i;
  }

  return ret;
}
int dp[1 << 16][16];
int dfs(int S, int v) {
  if (S + 1 == 1 << n)
    return dp[S][v] = 0;
  if (dp[S][v] != -1)
    return dp[S][v];
  int ret = 0;
  rep(u, n) {
    if (G[v][u] == INF)
      continue;
    if (!(S >> u & 1))
      ret = max(ret, dfs(S | 1 << u, u) + G[v][u]);
  }

  return dp[S][v] = ret;
}
void solve() {
  int sum = 0;
  vector<string> vec;
  rep(i, n) {
    bool f = true;
    rep(j, n) if (i != j) {
      if (cties[j].find(cties[i]) != string::npos)
        f = false;
    }
    if (f)
      vec.pb(cties[i]);
  }
  rep(i, vec.size()) sum += vec[i].size();
  rep(i, 20) rep(j, 20) G[i][j] = INF;
  rep(i, vec.size()) rep(j, vec.size()) if (i != j) {
    G[i][j] = dist(vec[i], vec[j]);
    G[j][i] = dist(vec[j], vec[i]);
  }
  int ans = INF;
  rep(v, n) {
    memset(dp, -1, sizeof(dp));
    int t = dfs(1 << v, v);
    // cout<<t<<endl;
    ans = min(ans, sum - t);
  }

  cout << ans << endl;
}

int main() {
  while (cin >> n) {
    if (n == 0)
      break;
    rep(i, n) cin >> cties[i];
    solve();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define all(c) (c).begin(), (c).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define pb(e) push_back(e)
#define mp(a, b) make_pair(a, b)
#define fr first
#define sc second

const int INF = 100000000;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
using namespace std;
typedef pair<int, int> P;
typedef long long ll;

int n;
string cties[20];
int G[20][20];

int dist(string s1, string s2) {
  if (s1.find(s2) != string::npos)
    return s2.size();
  int ret = 0;
  int m = min(s1.size(), s2.size());
  reverse(all(s1));
  rep(i, m) {
    string t = s1.substr(0, i);
    reverse(all(t));
    if (t == s2.substr(0, i))
      ret = i;
  }

  return ret;
}
int dp[1 << 16][16];
int dfs(int S, int v) {
  if (dp[S][v] != -1)
    return dp[S][v];
  if (S + 1 == 1 << n)
    return dp[S][v] = 0;
  int ret = INF;
  rep(u, n) {
    if (!(S >> u & 1))
      ret = min(ret, dfs(S | 1 << u, u) + G[v][u]);
  }

  return dp[S][v] = ret;
}
void solve() {
  int sum = 0;
  rep(i, n) sum += cties[i].size();
  rep(i, 20) rep(j, 20) G[i][j] = INF;
  rep(i, n) rep(j, n) if (i != j) {
    G[i][j] = -dist(cties[i], cties[j]);
    G[j][i] = -dist(cties[j], cties[i]);
  }
  int ans = INF;
  rep(v, n) {
    memset(dp, -1, sizeof(dp));
    int t = dfs(1 << v, v);
    // cout<<t<<endl;
    ans = min(ans, sum + t);
  }

  cout << ans << endl;
}

int main() {
  while (cin >> n) {
    if (n == 0)
      break;
    rep(i, n) cin >> cties[i];
    solve();
  }
  return 0;
}