Pagini recente » Cod sursa (job #3359429) | Cod sursa (job #3359265) | Cod sursa (job #3359256) | Cod sursa (job #3359258) | Cod sursa (job #3359259)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int INF = 1000000000;
int n, m;
string s[20], a[20];
int over[20][20], dp[1 << 18][18], tata[1 << 18][18];
vector<int> prefix(string p) {
vector<int> pi(p.size());
for(int i = 1; i < (int)p.size(); i++) {
int j = pi[i - 1];
while(j && p[i] != p[j]) {
j = pi[j - 1];
}
if(p[i] == p[j]) {
j++;
}
pi[i] = j;
}
return pi;
}
bool inside(string x, string y) {
string t = x + "#" + y;
vector<int> pi = prefix(t);
for(int v : pi) {
if(v == (int)x.size()) {
return 1;
}
}
return 0;
}
int getover(string x, string y) {
int lg = min(x.size(), y.size());
string t = y + "#" + x.substr(x.size() - lg);
vector<int> pi = prefix(t);
return pi.back();
}
int main() {
fin >> n;
for(int i = 0; i < n; i++) {
fin >> s[i];
}
sort(s, s + n);
n = unique(s, s + n) - s;
for(int i = 0; i < n; i++) {
int ok = 1;
for(int j = 0; j < n; j++) {
if(i != j && s[i].size() <= s[j].size() && inside(s[i], s[j])) {
ok = 0;
break;
}
}
if(ok) {
a[m++] = s[i];
}
}
n = m;
if(n == 0) {
fout << "\n";
return 0;
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i != j) {
over[i][j] = getover(a[i], a[j]);
}
}
}
int lim = 1 << n;
for(int mask = 0; mask < lim; mask++) {
for(int i = 0; i < n; i++) {
dp[mask][i] = INF;
tata[mask][i] = -1;
}
}
for(int i = 0; i < n; i++) {
dp[1 << i][i] = a[i].size();
}
for(int mask = 1; mask < lim; mask++) {
for(int last = 0; last < n; last++) {
if(dp[mask][last] == INF) {
continue;
}
for(int nxt = 0; nxt < n; nxt++) {
if(mask & (1 << nxt)) {
continue;
}
int nmask = mask | (1 << nxt);
int val = dp[mask][last] + (int)a[nxt].size() - over[last][nxt];
if(val < dp[nmask][nxt]) {
dp[nmask][nxt] = val;
tata[nmask][nxt] = last;
}
}
}
}
int mask = lim - 1, last = 0;
for(int i = 1; i < n; i++) {
if(dp[mask][i] < dp[mask][last]) {
last = i;
}
}
vector<int> ord;
while(last != -1) {
ord.push_back(last);
int p = tata[mask][last];
mask ^= 1 << last;
last = p;
}
reverse(ord.begin(), ord.end());
string ans = a[ord[0]];
for(int i = 1; i < (int)ord.size(); i++) {
int x = ord[i - 1], y = ord[i];
ans += a[y].substr(over[x][y]);
}
fout << ans;
return 0;
}