Pagini recente » Cod sursa (job #134535) | Cod sursa (job #85024) | Cod sursa (job #415317) | Cod sursa (job #218911) | Cod sursa (job #1632493)
#include <cstring>
#include <fstream>
#include <iostream>
using namespace std;
ifstream in("adn.in");
ofstream out("adn.out");
#define N 19
#define L 30002
int n;
char A[N][L];
int pred[L];
int v[N];
bool ok[N];
int lst[N], vf[N * N], urm[N * N], cost[N * N], nvf = 0;
int d[1 << N][N];
int t[1 << N][N];
int costuri[N][N];
int rez[N], nrez = 0;
inline bool kmp1(int x, int y)
{
int k = 0;
int l1 = strlen(1 + A[x]);
int l2 = strlen(1 + A[y]);
for(int i = 1; i <= l1; i++)
pred[i] = 0;
for(int i = 2; i <= l1; i++)
{
while(k != 0 && A[x][i] != A[x][1 + k])
k = pred[k];
if(A[x][i] == A[x][1 + k])
k++;
pred[i] = k;
}
k = 0;
for(int i = 1; i <= l2; i++)
{
while(k != 0 && A[y][i] != A[x][1 + k])
k = pred[k];
if(A[y][i] == A[x][1 + k])
k++;
if(k == l1)
return 1;
}
return 0;
}
inline int kmp2(int x, int y)
{
int k = 0;
int l1 = strlen(1 + A[x]);
int l2 = strlen(1 + A[y]);
for(int i = 1; i <= l1; i++)
pred[i] = 0;
for(int i = 2; i <= l1; i++)
{
while(k != 0 && A[x][i] != A[x][1 + k])
k = pred[k];
if(A[x][i] == A[x][1 + k])
k++;
pred[i] = k;
}
for(int i = 1; i <= l2; i++)
{
while(k != 0 && A[y][i] != A[x][1 + k])
k = pred[k];
if(A[y][i] == A[x][1 + k])
k++;
}
return k;
}
int main()
{
in >> n;
for(int i = 1; i <= n; i++)
{
in >> (1 + A[i]);
v[i - 1] = i;
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i != j && !ok[i] && !ok[j] && strlen(1 + A[i]) <= strlen(1 + A[j]) && kmp1(i, j))
ok[i] = 1;
}
for(int i = 0; i < n; i++)
while(ok[v[i]] && i < n)
{
swap(v[i], v[n - 1]);
n--;
}
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(i != j)
{
vf[++nvf] = j;
urm[nvf] = lst[i];
cost[nvf] = kmp2(v[i], v[j]);
lst[i] = nvf;
costuri[j][i] = cost[nvf];
}
for(int i = 2; i < (1 << n); i++)
{
for(int j = 0; j < n; j++)
if(i & (1 << j))
for(int k = lst[j]; k; k = urm[k])
if(i & (1 << vf[k]) && d[i][j] <= (d[i - (1 << j)][vf[k]] + cost[k]))
{
d[i][j] = d[i - (1 << j)][vf[k]] + cost[k];
t[i][j] = vf[k];
}
}
int maxim = 0, imax = 0;
for(int i = 0; i < n; i++)
{
if(d[(1 << n) - 1][i] > maxim)
{
maxim = d[(1 << n) - 1][i];
imax = i;
}
}
int mask = (1 << n) - 1;
while(mask)
{
rez[++nrez] = imax;
int aux = imax;
imax = t[mask][imax];
mask -= (1 << aux);
}
out << (1 + A[v[rez[nrez]]]);
for(int i = nrez - 1; i > 0; i--)
out << (1 + costuri[rez[i + 1]][rez[i]] + A[v[rez[i]]]);
out << '\n';
return 0;
}