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

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int inf = 0x3f3f3f3f;
int mp[30][30];
char str[20][122];
int dp[1 << 15][15];
int st[122];
int getval(char *a, char *b) {
  int la, lb, len;
  la = strlen(a), lb = strlen(b);

  for (int i = 0; i < la; i++)
    if (memcmp(&a[i], b, lb) == 0)
      return 0;

  for (len = min(la, lb); len > 0; len--) {
    int i, j;
    for (i = la - len, j = 0; j < len; i++, j++)
      if (a[i] != b[j])
        break;
    if (j == len)
      break;
  }
  return lb - len;
}

// int getval(int x,int y ){
//     int l1 = strlen(str[x]);
//     int l2 = strlen(str[y]);
//     if(l1 > l2)
//         for(int i = 0; i < l1; i++){
//             if(i + l2 > l1) break;
//             int h  = 0;
//             for(int j = 0; j < l2; j++){
//                 if(str[x][i+j] == str[y][j]){
//                      h++;
//                 }
//             }
//             if(h == l2) return 0;
//         }
//     int l = min(l1,l2),id = 0;
//     for(int i = l; i >= 1; i--){
//         bool flag = true;
//         for(int j = 0; j < i; j++){
//             if(str[x][l1 - (i - j)] == str[y][j] ) continue;
//             else {flag = false;break;}
//         }
//         if(flag) {id = i;break;}
//     }
//     //cout<<id<<endl;
//     return l2 - id;
// }
int main() {
  int N;
  while (cin >> N && N) {
    memset(st, 0, sizeof(st));
    for (int i = 0; i < N; i++) {
      scanf("%s", str[i]);
      st[i] = 1 << i;
    }
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        int t = getval(str[i], str[j]);
        if (t == 0) {
          st[i] |= 1 << j;
          mp[i][j] = 0;
        } else
          mp[i][j] = t;
        // cout<<i<<" "<<j<<" "<<mp[i][j]<<endl;
      }
    }
    memset(dp, -1, sizeof(dp));
    for (int i = 0; i < N; i++)
      dp[st[i]][i] = strlen(str[i]);

    for (int s = 0; s < (1 << N); s++)
      for (int i = 0; i < N; i++)
        if (dp[s][i] != -1) {
          for (int j = 0; j < N; j++)
            if (!(s & 1 << j)) {
              int tmp = s | st[j]; // s|1<<j;
              if (dp[tmp][j] == -1)
                dp[tmp][j] = dp[s][i] + mp[i][j];
              else
                dp[tmp][j] = min(dp[tmp][j], dp[s][i] + mp[i][j]);
            }
        }

    //        memset(dp,0x3f,sizeof(dp));
    //        for(int i = 0; i < N; i++){
    //                //cout<<s[i]<<endl;
    //                dp[1<<i][i] = strlen(str[i]);
    //        }
    //
    //        for(int i = 0; i < 1 << N; i++)
    //            for(int j = 0; j < N; j++){
    //                if(dp[i][j] == inf) continue;
    //               // cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
    //                for(int k = 0; k < N; k++) if(!(i & 1 << k))
    //                    dp[i|s[k]][k] = min(dp[i|s[k]][k],dp[i][j] +
    //                    mp[j][k]);
    //            }
    int ans = inf;
    for (int i = 0; i < N; i++)
      if (dp[(1 << N) - 1][i] != -1)
        ans = min(dp[(1 << N) - 1][i], ans);
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string.h>
#define oo 1000000000
using namespace std;
struct node {
  int fail, son[26], city, w;
} point[1001];
struct node2 {
  int len, x;
};
int n, m, k, g, arc[303][303], need[303], l[303], dp[2][303][18000];
char s[30];
queue<int> myqueue;
void Built_Trie() {
  int len, i, j, k, h, x;
  memset(point, 0, sizeof(point));
  m = 0;
  g = 1;
  for (k = 0; k < n; k++) {
    scanf("%s", s);
    len = strlen(s);
    h = 0;
    for (i = 0; i < len; i++) {
      x = s[i] - 'A';
      if (!point[h].son[x])
        point[h].son[x] = ++m;
      h = point[h].son[x];
    }
    point[h].w |= g;
    g *= 2;
  }
  g--;
  return;
}
void Built_AC_Automation() {
  int i, h, k;
  while (!myqueue.empty())
    myqueue.pop();
  for (i = 0; i < 26; i++)
    if (point[0].son[i])
      myqueue.push(point[0].son[i]);
  while (!myqueue.empty()) {
    h = myqueue.front();
    myqueue.pop();
    point[h].w |= point[point[h].fail].w;
    for (i = 0; i < 26; i++) {
      k = point[h].fail;
      while (!point[k].son[i] && k)
        k = point[k].fail;
      point[point[h].son[i]].fail = point[k].son[i];
      if (!point[h].son[i])
        point[h].son[i] = point[k].son[i];
      else
        myqueue.push(point[h].son[i]);
    }
  }
  return;
}
void Built_Arc() {
  int i, k, h, len[303];
  memset(arc, -1, sizeof(arc));
  n = 0;
  for (k = 0; k <= m; k++)
    if (point[k].w) {
      need[n++] = k;
      point[k].city = n;
    }
  need[n] = 0;
  for (k = 0; k <= n; k++) {
    h = need[k];
    memset(len, -1, sizeof(len));
    myqueue.push(h);
    len[h] = 0;
    while (!myqueue.empty()) {
      h = myqueue.front();
      myqueue.pop();
      i = h;
      do {
        if (point[h].w && arc[k][point[h].city - 1] == -1)
          arc[k][point[h].city - 1] = len[h];
        i = point[i].fail;
      } while (i);
      for (i = 0; i < 26; i++)
        if (len[point[h].son[i]] == -1) {
          len[point[h].son[i]] = len[h] + 1;
          myqueue.push(point[h].son[i]);
        }
    }
  }
  for (i = 0; i < n; i++)
    l[i] = arc[n][i];
  return;
}
int EXE_DP() {
  int p, i, j, t, k, x, ans;
  memset(dp, -1, sizeof(dp));
  k = 0;
  for (i = 0; i < n; i++)
    dp[k][i][point[need[i]].w] = l[i];
  for (t = 1; t <= n; t++) {
    k = 1 - k;
    memset(dp[k], -1, sizeof(dp[k]));
    for (i = 0; i < n; i++)
      for (j = 0; j < n; j++)
        for (p = 0; p <= g; p++)
          if (dp[1 - k][j][p] != -1) {
            x = point[need[i]].w | p;
            if (dp[k][i][x] == -1 || dp[k][i][x] > dp[1 - k][j][p] + arc[j][i])
              dp[k][i][x] = dp[1 - k][j][p] + arc[j][i];
          }
  }
  ans = oo;
  for (i = 0; i < n; i++)
    if (dp[k][i][g] != -1 && dp[k][i][g] < ans)
      ans = dp[k][i][g];
  return ans;
}
int main() {
  while (~scanf("%d", &n)) {
    if (!n)
      break;
    Built_Trie();
    Built_AC_Automation();
    Built_Arc();
    printf("%d\\n", EXE_DP());
  }
  return 0;
}