Pagini recente » Cod sursa (job #1949503) | Cod sursa (job #1770917) | Cod sursa (job #719746) | Cod sursa (job #299673) | Cod sursa (job #1488217)
#include <fstream>
#include <cstring>
#include <algorithm>
#include <vector>
#define DIM 18
#define LEN 30005
#define infile "adn.in"
#define outfile "adn.out"
using namespace std;
ifstream fin(infile);
ofstream fout(outfile);
char seq[DIM + 1][LEN];
int pi[DIM + 1][LEN];
int cost[DIM +1][DIM + 1];
int sol[DIM + 1], w[DIM + 1];
bool useless[DIM];
int dp[1 << DIM][DIM + 1], t[1 << DIM][DIM + 1];
int main() {
int n;
fin >> n;
for (int i = 1; i <= n; ++i) {
fin >> seq[i] + 1;
}
//prefix function
for (int i = 1; i <= n; ++i) {
int q;
for (int j = 2; seq[i][j]; ++j) {
q = pi[i][j - 1];
while (q && seq[i][j] != seq[i][q + 1])
q = pi[i][q];
if (seq[i][j] == seq[i][q + 1])
pi[i][j] = q + 1;
}
}
//merge cost
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (i == j)
continue;
cost[i][j] = -1;
int q = 0;
for (int pos = 1; seq[i][pos]; ++pos) {
while (q && seq[i][pos] != seq[j][q + 1])
q = pi[j][q];
if(seq[i][pos] == seq[j][q + 1])
++q;
if (q == strlen(seq[j] + 1)) {
cost[i][j] = 0;
useless[j] = true;
break;
}
}
if (cost[i][j] == -1) {
cost[i][j] = strlen(seq[j] + 1) - q;
}
}
}
int m = 0;
for (int i = 1; i <= n; ++i)
if (!useless[i])
w[++m] = i;
//dynamic programming
for (int config = 1, i = 1; config < (1 << m); config <<= 1, ++i) {
dp[config][i] = 0;
t[config][i] = -1;
}
for (int config = 1; config < (1 << m); ++config) {
if (!(config & (config - 1)))
continue;
for (int i = 1; i <= m; ++i) {
if (!(config & (1 << (i - 1))))
continue;
dp[config][i] = 2000000000;
t[config][i] = -1;
for (int j = 1; j <= m; ++j) {
if (i == j || !(config & (1 << (j - 1))))
continue;
int aux = dp[config ^ (1 << (i - 1))][j] + cost[w[j]][w[i]];
if (aux < dp[config][i]) {
dp[config][i] = aux;
t[config][i] = j;
}
}
}
}
int last, minim = 2000000000;
for (int i = 1; i <= m; ++i) {
if (minim > dp[(1 << m) - 1][i]) {
minim = dp[(1 << m) - 1][i];
last = i;
}
}
int nr = 0, config = (1 << m) - 1;
while (last != -1) {
sol[++nr] = w[last];
last = t[config][last];
config ^= (1 << (last - 1));
}
fout << seq[sol[nr]];
for (int i = nr - 1; i; --i) {
for (int j = strlen(seq[sol[nr]] + 1) - cost[sol[nr + 1]][sol[nr]] + 1; seq[sol[nr]][j]; ++j)
fout << seq[sol[nr]][j];
}
return 0;
}
//Trust me, I'm the Doctor!