Pagini recente » Cod sursa (job #1120979) | Cod sursa (job #493249) | Cod sursa (job #611942) | Cod sursa (job #2011754) | Cod sursa (job #1001272)
#include <cstdio>
#include <cstring>
#include <bitset>
#include <stack>
#define ml first
#define prev second.first
#define niv second.second
using namespace std;
const int NMAX = 19, LMAX = 30003;
bitset <NMAX> valid;
pair <int, pair <int, int> > D[1 << NMAX - 1][NMAX];
stack <short> order;
short prefix[NMAX][LMAX], lengths[NMAX], cost[NMAX][NMAX];
char s[NMAX][LMAX];
inline void make_prefix (char *S, short *V, const short len) {
short i, k = 0;
for (i = 2; i <= len; ++i) {
while (k && S[k + 1] != S[i])
k = V[k];
if (S[k + 1] == S[i])
++k;
V[i] = k;
}
}
inline int make_cost (const short &x, const short &y) {
short i, k = 0;
for (i = 1; i <= lengths[x]; ++i) {
while (k && s[x][i] != s[y][k + 1])
k = prefix[y][k];
if (s[x][i] == s[y][k + 1])
++k;
if (k == lengths[y]) {
valid[y] = 0;
return -1;
}
}
return k;
}
int main () {
freopen ("adn.in", "r", stdin);
freopen ("adn.out", "w", stdout);
int i, l, j, k, a;
short N;
scanf ("%d\n", &N);
valid.set ();
for (i = 1; i <= N; ++i) {
fgets (s[i] + 1, LMAX, stdin);
lengths[i] = strlen (s[i] + 1);
s[i][lengths[i]--] = 0;
make_prefix (s[i], prefix[i], lengths[i]);
for (j = i - 1; j; --j)
cost[i][j] = make_cost (i, j),
cost[j][i] = make_cost (j, i);
}
l = 1 << N;
for (i = 1; i < l; ++i) {
for (j = 1; j <= N; ++j) /// in j se termina
if (i & 1 << (j - 1) && valid[j]) {
for (k = 1; k < j; ++k)
if (i & 1 << (k - 1) && valid[k] && cost[k][j] + D[i ^ (1 << j - 1)][k].ml >= D[i][j].ml)
D[i][j] = make_pair (cost[k][j] + D[i ^ (1 << j - 1)][k].ml, make_pair (k, i ^ (1 << j - 1)));
for (k = j + 1; k <= N; ++k)
if (i & 1 << (k - 1) && valid[k] && cost[k][j] + D[i ^ (1 << j - 1)][k].ml >= D[i][j].ml)
D[i][j] = make_pair (cost[k][j] + D[i ^ (1 << j - 1)][k].ml, make_pair (k, i ^ (1 << j - 1)));
}
}
i = 1;
for (j = 2; j <= N; ++j)
if (D[l - 1][i].ml < D[l - 1][j].ml)
i = j;
j = l - 1;
k = i;
while (k)
order.push (k),
a = k,
k = D[j][k].prev,
j = D[j][a].niv;
printf ("%s", s[k = order.top ()] + 1);
order.pop ();
while (!order.empty ())
printf ("%s", &s[order.top ()][cost[k][order.top ()] + 1]),
k = order.top (),
order.pop ();
}