Pagini recente » Cod sursa (job #190597) | Cod sursa (job #529128) | Cod sursa (job #1241903) | Cod sursa (job #274665) | Cod sursa (job #1250404)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int INF = 2e9, NMAX = 18, LENMAX = 30005;
int len[NMAX + 5], d[1 << NMAX][NMAX + 5], lmin[1 << NMAX][NMAX + 5], match[NMAX + 5][NMAX + 5];
char sir[NMAX + 5][LENMAX], sol[LENMAX * NMAX];
vector <int> res;
int kmp (int a, int b) {
int i, p, pi[LENMAX];
p = 0;
pi[1] = 0;
for(i = 2; i <= len[b]; ++ i) {
while(p && sir[b][p + 1] != sir[b][i])
p = pi[p];
if(sir[b][p + 1] == sir[b][i])
++ p;
pi[i] = p;
}
p = 0;
for(i = 1; i <= len[a]; ++ i) {
while(p && sir[b][p + 1] != sir[a][i])
p = pi[p];
if(sir[b][p + 1] == sir[a][i])
++ p;
}
return p;
}
bool testBit (int x, int bit) {
return x & (1 << bit);
}
int main() {
freopen("adn.in", "r", stdin);
freopen("adn.out", "w", stdout);
int i, n, j, subset, last, l, newSet;
scanf("%d\n", &n);
for(i = 0; i < n; ++ i) {
scanf("%s", sir[i] + 1);
len[i] = strlen(sir[i] + 1);
lmin[1 << i][i] = len[i];
}
for(i = 0; i < n; ++ i)
for(j = 0; j < n; ++ j)
if(i != j)
match[i][j] = kmp(i, j);
for(subset = 1; subset < (1 << n); ++ subset)
for(last = 0; last < n; ++ last)
if(testBit(subset, last) && lmin[subset][last])
for(i = 0; i < n; ++ i)
if(!testBit(subset, i)) {
newSet = subset | (1 << i);
if(lmin[newSet][i] == 0 || lmin[newSet][i] > lmin[subset][last] + len[i] - match[last][i])
lmin[newSet][i] = lmin[subset][last] + len[i] - match[last][i],
d[newSet][i] = last;
// fprintf(stderr, "%d %d - %d\n", newSet, i, lmin[newSet][i]);
}
subset = (1 << n) - 1;
l = INF;
for(i = 0; i < n; ++ i)
if(lmin[subset][i] && lmin[subset][i] < l) {
l = lmin[subset][i];
last = i;
}
while(subset) {
i = d[subset][last];
res.push_back(last);
subset ^= (1 << last);
last = i;
}
reverse(res.begin(), res.end());
l = 0;
strcat(sol, sir[res[0]] + 1);
for(i = 1; i < res.size(); ++ i)
strcat(sol, sir[res[i]] + 1 + match[res[i - 1]][res[i]]);
printf("%s\n", sol);
return 0;
}