Pagini recente » Statistici Goina Tudor David (Tudi10) | Atasamentele paginii Profil TukTukhachevsky | Statistici Juganaru Elena-Alexandra (alexaandraaaj) | Profil razor | Cod sursa (job #3359550)
#include <bits/stdc++.h>
using namespace std;
#define FASTIO ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
ifstream fin ("adn.in");
ofstream fout ("adn.out");
int lps[60010], dp[1 << 18][18], p[1 << 18][18];
bool is_included(string a, string b)
{
int n = a.length(), m = b.length();
if(m <= n) return 0;
int k = 0;
for(int i = 2; i <= n; i++){
while(k != 0 && a[k] != a[i - 1])
k = lps[k];
if(a[k] == a[i - 1]) k++;
lps[i] = k;
}
k = 0;
int nrs = 0;
for(int i = 1; i <= m; i++){
while(k != 0 && a[k] != b[i - 1])
k = lps[k];
if(a[k] == b[i - 1]) k++;
if(k == n) return 1;
}
return 0;
}
int calculate_cost(string a, string b){
string x = b + "#" + a;
int n = x.size();
int k = 0;
for(int i = 2; i <= n; i++){
while(k != 0 && x[k] != x[i - 1])
k = lps[k];
if(x[k] == x[i - 1]) k++;
lps[i] = k;
}
return b.size() - lps[n];
}
int main()
{
FASTIO
int n; fin >> n;
vector<string> a;
for(int i = 1; i <= n; i++){
string x; fin >> x;
a.push_back(x);
}
vector<bool> nv(n);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(i != j && (is_included(a[i], a[j]) || (i < j && a[i] == a[j]))) nv[i] = 1;
vector<string> s;
for(int i = 0; i < n; i++)
if(!nv[i]) s.push_back(a[i]);
n = s.size();
vector<vector<int>> c(20, vector<int>(20));
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(i != j) c[i][j] = calculate_cost(s[i], s[j]);
for(int mask = 0; mask < (1 << n); mask++){
for(int i = 0; i < n; i++){
dp[mask][i] = 1e9;
p[mask][i] = -1;
}
}
for(int i = 0; i < n; i++){
dp[1 << i][i] = s[i].length();
}
for(int mask = 1; mask < (1 << n); mask++)
for(int i = 0; i < n; i++){
if(!(mask & (1 << i))) continue;
if(dp[mask][i] == 1e9) continue;
for(int j = 0; j < n; j++){
if(!(mask & (1 << j))){
int nmask = mask | (1 << j);
if(dp[mask][i] + c[i][j] < dp[nmask][j]){
dp[nmask][j] = dp[mask][i] + c[i][j];
p[nmask][j] = i;
}
}
}
}
int mn = 2e9;
int ult = -1;
int fmask = (1 << n) - 1;
for(int i = 0; i < n; i++){
if(dp[fmask][i] < mn){
mn = dp[fmask][i];
ult = i;
}
}
vector<int> ord;
int curr_mask = fmask;
while(ult != -1){
ord.push_back(ult);
int prv = p[curr_mask][ult];
curr_mask ^= (1 << ult);
ult = prv;
}
reverse(ord.begin(), ord.end());
string sol = s[ord[0]];
n = ord.size();
for(int i = 1; i < n; i++){
int a = ord[i-1];
int b = ord[i];
sol += s[b].substr(s[b].length() - c[a][b]);
}
fout << sol << "\n";
return 0;
}