Pagini recente » Cod sursa (job #1747289) | Cod sursa (job #693963) | Cod sursa (job #2932887) | Cod sursa (job #738960) | Cod sursa (job #2927445)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int kN = 18;
const int INF = 1e9;
int wt[kN][kN];
pair<int, int> dp[kN][1 << kN];
void maxSelf(int &x, int y) {
if (x < y) {
x = y;
}
}
vector<int> preffixFunction(const string &s) {
int n = s.size() - 1;
vector<int> pi(n + 1);
for (int i = 2, q = 0; i <= n; ++i) {
while (q && s[q + 1] != s[i]) {
q = pi[q];
}
if (s[q + 1] == s[i]) {
q += 1;
}
pi[i] = q;
}
return pi;
}
bool check(const string &s, const string &t) {
vector<int> pi = preffixFunction('#' + s + '#' + t);
if (*max_element(pi.begin(), pi.end()) == (int)s.size()) {
return true;
}
return false;
}
int findSuffix(const string &s, const string &t) {
return preffixFunction('#' + s + '#' + t).back();
}
int main() {
int n;
fin >> n;
vector<string> s(n);
for (auto &it : s) {
fin >> it;
}
vector<string> newS;
for (int i = 0; i < n; ++i) {
bool flag = true;
for (int j = 0; j < n; ++j) {
if (i != j && check(s[i], s[j])) {
flag = false;
break;
}
}
if (flag) {
newS.emplace_back(s[i]);
}
}
s = newS;
n = s.size();
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i != j) {
wt[i][j] = findSuffix(s[j], s[i]);
}
}
}
for (int mask = 3; mask < (1 << n); ++mask) {
if (__builtin_popcount(mask) > 1) {
for (int start = 0; (1 << start) <= mask; ++start) {
if (mask & (1 << start)) {
int newMask = mask ^ (1 << start);
for (int nxt = 0; (1 << nxt) <= newMask; ++nxt) {
if (newMask & (1 << nxt)) {
dp[start][mask] = max(dp[start][mask], {dp[nxt][newMask].first + wt[start][nxt], nxt});
}
}
}
}
}
}
int best = 0, curr = 0;
for (int i = 0; i < n; ++i) {
if (best < dp[i][(1 << n) - 1].first) {
best = dp[i][(1 << n) - 1].first;
curr = i;
}
}
int mask = (1 << n) - 1, pref = -1;
string sol = "";
while (mask) {
for (int i = pref + 1; i < (int)s[curr].size(); ++i) {
sol += s[curr][i];
}
int nxt = dp[curr][mask].second;
mask ^= 1 << curr;
pref = wt[curr][nxt];
curr = nxt;
}
fout << sol << '\n';
fin.close();
fout.close();
return 0;
}