Pagini recente » Cod sursa (job #3350783) | Cod sursa (job #3242397) | Cod sursa (job #1536417) | Cod sursa (job #3311347) | Cod sursa (job #3338940)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <climits>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int MAXL = 30002;
const int MAXN = 19;
int cost[MAXN][MAXN];
int phi[MAXL];
string s[MAXN];
bool included[MAXN];
int N, mask_included;
int dp[1 << MAXN][MAXN], prev_dp[1 << MAXN][MAXN];
vector<int> order;
int main()
{
fin >> N;
for (int i = 0; i < N; ++i) {
fin >> s[i];
}
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (i == j) continue;
const auto& a = s[i];
const auto& b = s[j];
int k = 0;
phi[1] = 0;
for (int t = 1; t < b.length(); ++t) {
while (k && b[k] != b[t]) k = phi[k];
if (b[k] == b[t]) {
++k;
}
phi[t + 1] = k;
}
k = 0;
for (int t = 0; t < a.length(); ++t) {
while (k && b[k] != a[t]) k = phi[k];
if (b[k] == a[t]) ++k;
if (k == b.length()) {
included[j] = true;
k = phi[k];
}
}
cost[i][j] = b.length() - k;
}
}
for (int i = 0; i < N; ++i) {
if (included[i]) mask_included |= 1 << i;
}
// In case all sequences are equal.
if (mask_included == (1 << N) - 1) {
--mask_included;
}
for (int mask = 0; mask < (1 << N); ++mask) {
for (int i = 0; i < N; ++i) {
dp[mask][i] = INT_MAX / 2;
}
}
for (int i = 0; i < N; ++i) {
if (!included[i]) dp[1 << i][i] = s[i].length();
}
for (int mask = 0; mask < (1 << N); ++mask) {
if (mask & mask_included) continue;
if ((mask & (-mask)) == mask) continue;
for (int last = 0; last < N; ++last) {
if (!(mask & (1 << last))) continue;
for (int prev = 0; prev < N; ++prev) {
if (!(mask & (1 << prev))) continue;
if (prev == last) continue;
if (dp[mask][last] > dp[mask - (1 << last)][prev] + cost[prev][last]) {
dp[mask][last] = dp[mask - (1 << last)][prev] + cost[prev][last];
prev_dp[mask][last] = prev;
}
}
}
}
int desired_mask = (1 << N) - 1 - mask_included;
int start = 0;
for (int i = 0; i < N; ++i) {
if (dp[desired_mask][i] < dp[desired_mask][start]) {
start = i;
}
}
while (desired_mask) {
order.push_back(start);
const int prev = prev_dp[desired_mask][start];
desired_mask -= 1 << start;
start = prev;
}
reverse(order.begin(), order.end());
std::string result = s[order[0]];
for (int i = 1; i < order.size(); ++i) {
const string& a = s[order[i]];
const int& c = cost[order[i - 1]][order[i]];
for (int j = a.length() - c; j < a.length(); ++j) {
result.push_back(a[j]);
}
}
fout << result;
return 0;
}