Pagini recente » Cod sursa (job #197224) | Cod sursa (job #1644950) | Cod sursa (job #3221120) | Cod sursa (job #2934479) | Cod sursa (job #134)
Cod sursa(job #134)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int NMAX = 18;
const int MMAX = 30005;
int N, Nr;
char A[NMAX][MMAX];
int D[NMAX][NMAX];
bool V[NMAX];
int DP[NMAX][1 << NMAX], P[NMAX][1 << NMAX];
void citire() {
FILE *fin = fopen("adn.in", "rt");
int i;
fscanf(fin, " %d", &N);
Nr = N;
for (i = 0; i < N; ++i)
fscanf(fin, " %s", A[i]),
V[i] = true;
fclose(fin);
}
int kmp(char T[], char P[]) {
int pi[MMAX];
int i, j;
int N, M;
N = strlen(T);
M = strlen(P);
pi[0] = pi[1] = 0;
for (j = 0, i = 2; i <= M; ++i) {
while (j > 0 && P[j] != P[i - 1]) j = pi[j];
if (P[j] == P[i - 1]) ++j;
pi[i] = j;
}
for (j = 0, i = 1; i <= N; ++i) {
while (j > 0 && P[j] != T[i - 1]) j = pi[j];
if (P[j] == T[i - 1]) ++j;
if (j == M)
return -1;
}
return M - j;
}
void graf() {
int i, j, aux;
memset(D, 0x3f, sizeof(D));
for (i = 0; i < N; ++i)
for (j = 0; j < N && V[i]; ++j)
if (i != j && V[j]) {
aux = kmp(A[i], A[j]);
if (aux != -1)
D[i][j] = aux;
else
V[j] = false,
--Nr;
}
}
int back(int k, int q, int c) {
if (k == Nr) return 0;
if (DP[c][q] != -1) return DP[c][q];
int i, min, poz, aux;
min = INF; poz = -1;
for (i = 0; i < N; ++i)
if ((q & (1 << i)) == 0 && V[i]) {
aux = D[c][i] + back(k + 1, q | (1 << i), i);
if (aux < min)
min = aux,
poz = i;
}
P[c][q] = poz;
return DP[c][q] = min;
}
void afisare() {
FILE *fout = fopen("adn.out", "wt");
int i, min, poz, aux, t;
min = INF; poz = -1;
memset(DP, 0xff, sizeof(DP));
for (i = 0; i < N; ++i)
if (V[i]) {
aux = strlen(A[i]) + back(1, 1 << i, i);
if (min > aux)
min = aux,
poz = i;
}
fprintf(fout, "%s", A[poz]);
aux = 1 << poz;
for (i = 1; i < Nr; ++i) {
t = P[poz][aux];
fprintf(fout, "%s", A[t] + strlen(A[t]) - D[poz][t]);
aux |= 1 << t;
poz = t;
}
fprintf(fout, "\n");
fclose(fout);
}
int main() {
citire();
graf();
afisare();
return 0;
}