Pagini recente » Cod sursa (job #1063684) | Cod sursa (job #590191) | Cod sursa (job #2459868) | Cod sursa (job #21189) | Cod sursa (job #629070)
Cod sursa(job #629070)
#include <cstdio>
#include <bitset>
#include <cstring>
#include <iostream>
using namespace std;
FILE* fin = fopen("adn.in", "r");
int n, mask;
const int maxn = 20, maxs = 30010, inf = 0x3f3f3f3f;
bitset<maxn> ban;
char dna[maxn][maxs];
int d[maxn][maxn], c[1 << maxn][maxn], last[1 << maxn][maxn], pi[maxs], len[maxn];
int kmp(int a)
{
pi[1] = 0;
for (int q = 2, k = 0; q <= len[a]; ++q) {
while (k && dna[a][k + 1] != dna[a][q]) {
k = pi[k];
}
if (dna[a][k + 1] == dna[a][q]) {
++k;
}
pi[q] = k;
}
for (int b = 1; b <= n; ++b) {
if (a == b) {
continue;
}
int k = 0;
bool include = false;
for (int i = 1; !include && i <= len[b]; ++i) {
while (k && dna[a][k + 1] != dna[b][i]) {
k = pi[k];
}
if (dna[a][k + 1] == dna[b][i]) {
++k;
}
if (k == len[a]) {
include = true;
break;
}
}
if (include) {
d[b][a] = -1;
ban[a] = true;
mask &= ((1 << n) - 1 - (1 << (a - 1)));
} else {
d[b][a] = k;
}
}
}
void recover(int i, int j)
{
if (i) {
int prec = last[i][j];
if (prec) {
recover(i ^ (1 << (j - 1)), prec);
cout << dna[j] + 1 + d[prec][j];
} else {
cout << dna[j] + 1;
}
}
}
int main()
{
fscanf (fin, "%d\n", &n);
freopen("adn.out", "w", stdout);
mask = (1 << n) - 1;
for (int i = 1; i <= n; ++i) {
fscanf (fin, "%s\n", dna[i] + 1);
len[i] = strlen(dna[i] + 1);
}
for (int i = 1; i <= n; ++i) {
kmp(i);
}
for (int i = 0; i < (1 << n); ++i) {
for (int j = 1; j <= n; ++j) {
if (!ban[j] && i & (1 << (j - 1))) {
for (int k = 1; k <= n; ++k) {
if (k != j && !ban[k] && i & (1 << (k - 1))) {
int cost = c[i ^ (1 << (j - 1))][k] + d[k][j];
if (c[i][j] <= cost) {
c[i][j] = cost;
last[i][j] = k;
}
}
}
}
}
}
int lst = 0;
for (int i = 1; i <= n; ++i) {
if (c[mask][lst] <= c[mask][i]) {
lst = i;
}
}
recover(mask, lst);
cout << endl;
fclose(fin);
return 0;
}