Pagini recente » Cod sursa (job #1004118) | Cod sursa (job #1483087) | Cod sursa (job #1187342) | Cod sursa (job #3275898) | Cod sursa (job #2105779)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int NMAX = 18 + 5;
const int PMAX = (1 << 18) + 5;
const int LMAX = 30001 + 5;
const int INF = 0x3f3f3f3f;
vector <int> v;
int n;
int len[NMAX], phi[NMAX];
char lant[NMAX][LMAX];
bool useless[NMAX];
int comun[NMAX][NMAX];
int dp[NMAX][PMAX];
void prefix(int node)
{
for (int i = 2; i <= len[node]; ++i)
{
int last = phi[i - 1];
while (last > 0 && lant[node][i] != lant[node][last + 1]) last = phi[last];
if (lant[node][i] == lant[node][last + 1]) phi[i] = last + 1;
}
}
bool kmp (int pref, int node)
{
int k = 0;
for (int i = 1; i <= len[node]; ++i)
{
while (k > 0 && lant[node][i] != lant[pref][k + 1]) k = phi[k];
if (lant[node][i] == lant[pref][k + 1]) ++k;
if (k == len[pref])
{
comun[node][pref] = 0;
return true;
}
if (i == len[pref] && comun[node][pref])
comun[node][pref] = len[node] - k;
}
return false;
}
void read()
{
fin >> n;
for (int i = 1; i <= n; ++i)
{
fin >> (lant[i] + 1);
len[i] = strlen(lant[i] + 1);
}
}
int main()
{
read();
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (i != j)
{
comun[j][i] = -1;
prefix(i);
useless[i] = max(useless[i], kmp(i, j));
//comun[j][i] = lant[j][len[j]];
}
for (int i = 1; i <= n; ++i)
if (!useless[i])
v.push_back(i);
n = v.size();
for (int conf = 1; conf < (1 << n); conf++)
for (int i = 0; i < n; i++)
if (conf & (1 << i))
{
dp[conf][i] = 1 << 30; /// inf
int aux = conf - (1 << i);
if (aux == 0) dp[conf][i] = len[v[i]];
else for (int j = 0; j < n; j++)
if (aux & (1 << j))
dp[conf][i] = min(dp[conf][i], dp[aux][j] + len[v[i]] - comun[v[j]][v[i]]);
}
int sol = 1 << 30;
for (int i = 0; i < n; i++)
sol = min(sol, dp[(1 << n) - 1][i]);
fout << sol << "\n";
return 0;
}