Pagini recente » Cod sursa (job #904181) | Cod sursa (job #2293936) | Cod sursa (job #1314671) | Cod sursa (job #1055754) | Cod sursa (job #1532822)
#include <fstream>
#include <algorithm>
#include <cstring>
#include <tuple>
using namespace std;
ifstream in("adn.in");
ofstream out("adn.out");
const int MAX_N = 18;
const int MAX_LEN = 30000;
const int MAX_CFG = 1 << MAX_N;
const int INF = 0x7fffffff;
int n;
int R[MAX_CFG][1 + MAX_N];
int D[MAX_CFG][1 + MAX_N];
int C[1 + MAX_N][1 + MAX_N];
char S[1 + MAX_N][MAX_LEN + 5];
int P[5 + MAX_LEN];
int L[1 + MAX_N];
bool DEL[1 + MAX_N];
int substring(int u, int v) {
int i, q, lu, lv, ans, side;
lu = strlen(S[u] + 1);
lv = strlen(S[v] + 1);
if(lu > lv) {
swap(u, v);
swap(lu, lv);
}
memset(P, 0, sizeof(P));
for(i = 2, q = 0; i <= lu; i++) {
while(q > 0 && S[u][q + 1] != S[u][i]) q = P[q];
if(S[u][q + 1] == S[u][i]) q++;
P[i] = q;
}
for(i = 1, q = 0; i <= lv; i++) {
while(q > 0 && S[u][q + 1] != S[v][i]) q = P[q];
if(S[u][q + 1] == S[v][i]) q++;
if(q == lu) {
return u;
}
}
return 0;
}
int getEdgeCost(int u, int v) {
int lu = L[u], lv = L[v], i, q;
memset(P, 0, sizeof(P));
for(i = 2, q = 0; i <= lv; i++) {
while(q > 0 && S[v][q + 1] != S[v][i]) q = P[q];
if(S[v][q + 1] == S[v][i]) q++;
P[i] = q;
}
for(i = 1, q = 0; i <= lu; i++) {
while(q > 0 && S[v][q + 1] != S[u][i]) q = P[q];
if(S[v][q + 1] == S[u][i]) q++;
}
return q;
}
void printSol(int cfg, int last) {
if((cfg & (cfg - 1)) == 0) {
out << S[last + 1] + 1;
}
else {
printSol(cfg - (1 << last), R[cfg][last]);
out << S[last + 1] + 1 + C[R[cfg][last]][last];
}
}
int main() {
int i, j, k, cfg, last, len;
in >> n;
for(i = 1; i <= n; i++) in >> S[i] + 1;
for(i = 1; i <= n; i++) {
for(j = i + 1; j <= n; j++) {
DEL[substring(i, j)] = true;
}
}
for(i = 0, j = 1; j <= n; j++) {
if(!DEL[j]) {
i++;
strcpy(S[i] + 1, S[j] + 1);
}
}
n = i;
for(i = 1; i <= n; i++) {
L[i] = strlen(S[i] + 1);
}
for(i = 1; i <= n; i++) {
for(j = 1; j <= n; j++) {
if(i != j) {
C[i - 1][j - 1] = getEdgeCost(i, j);
}
}
}
for(i = 1; i < (1 << n); i++) {
for(j = 0; j < n; j++) {
D[i][j] = INF;
R[i][j] = 0;
}
}
for(i = 0; i < n; i++) {
D[1 << i][i] = L[i + 1];
R[i][j] = 0;
}
for(i = 1; i < (1 << n); i++) {
for(j = 0; j < n; j++) {
if(i & (1 << j)) {
cfg = i - (1 << j);
for(k = 0; k < n; k++) {
if(cfg & (1 << k)) {
if(D[i][j] > D[cfg][k] + L[j + 1] - C[k][j]) {
D[i][j] = D[cfg][k] + L[j + 1] - C[k][j];
R[i][j] = k;
}
}
}
}
}
}
for(i = 0, len = INF; i < n; i++) {
if(len > D[(1 << n) - 1][i]) {
len = D[(1 << n) - 1][i];
last = i;
}
}
printSol((1 << n) - 1, last);
}