Pagini recente » Cod sursa (job #908738) | Cod sursa (job #2087076) | Cod sursa (job #1750473) | Cod sursa (job #965990) | Cod sursa (job #1625838)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define MAXLEN 30050
#define MAXN 20
using namespace std;
char s[MAXN][MAXLEN];
int n, rez;
int comun[MAXN][MAXN], pref[MAXN][MAXLEN], memo[MAXN][1<<18];
vector<int> nods;
vector<char> sol;
int mask;
void citire()
{
scanf("%d\n", &n);
for (int i = 0; i < n; i++) {
gets(s[i]);
int t = strlen(s[i]);
for (int j = t; j >= 1; j--)
s[i][j] = s[i][j-1];
}
mask = (1<<n)-1;
for (int i = 0; i < n; i++)
for (int j = 0; j <= mask; j++)
memo[i][j] = -1;
}
void prefixes(int ind)
{
pref[ind][1] = 0;
int crt = 0;
for (int i = 2, t = strlen(s[ind]); i < t; i++) {
while (crt > 0 && s[ind][crt+1] != s[ind][i])
crt = pref[ind][crt];
if (s[ind][crt+1] == s[ind][i])
crt++;
pref[ind][i] = crt;
}
}
int calculate(int x, int y)
{
int crt = 0;
for (int i = 0; s[x][i]; i++) {
if (crt > 0 && s[y][crt+1] != s[x][i])
crt = pref[y][crt];
if (s[y][crt+1] == s[x][i])
crt++;
if (crt == strlen(s[y])-1)
return strlen(s[y]);
}
return crt;
}
void process()
{
for (int i = 0; i < n; i++)
prefixes(i);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (i != j)
comun[i][j] = calculate(i, j)+1;
}
int hamilton(int nod, int mask)
{
if (1<<nod == mask)
memo[nod][mask] = 0;
if (memo[nod][mask] != -1)
return memo[nod][mask];
int maxi = 0;
for (int i = 0; i < n; i++)
if (i!= nod && (mask&(1<<i))) {
int val = hamilton(i, mask - (1<<nod));
if (val + comun[i][nod] > maxi)
maxi = val + comun[i][nod];
}
memo[nod][mask] = maxi;
return maxi;
}
void getSolution(int ind)
{
nods.push_back(ind);
int crt = mask, p = ind;
for (; crt != (1<<p); ) {
for (int i = 0; i < n; i++)
if (crt&(1<<i) && memo[i][crt-(1<<p)] + comun[i][p] == memo[p][crt]) {
crt -= (1<<p);
nods.push_back(i);
p = i;
break;
}
}
// for (int i = nods.size()-1; i >= 0; i--)
// printf("%d ", nods[i]);
}
void solve()
{
// for (int i = 0; i < n; i++, printf("\n"))
// for (int j = 0; j < n; j++)
// printf("%d ", comun[i][j]);
rez = -1;
int total = 0, pos = 0;
for (int i = 0; i < n; i++) {
int val = hamilton(i, mask);
if (val > rez) {
pos = i;
rez = val;
}
}
getSolution(pos);
for (int i = 0; i < n; i++)
total += strlen(s[i]);
for (int i = nods.size()-1; i >= 0; i--) {
int j = (i < nods.size()-1 ? comun[nods[i+1]][nods[i]] : 1);
for (j; s[nods[i]][j]; j++)
printf("%c", s[nods[i]][j]);
}
//printf("%d", total-rez);
}
int main()
{
freopen("adn.in", "r", stdin);
freopen("adn.out", "w", stdout);
citire();
process();
solve();
return 0;
}