Pagini recente » Borderou de evaluare (job #2007300) | Cod sursa (job #2918675)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
const int N = 18, inf = 1e9 + 1;
int n, cost[N + 1][N + 1];
string vaux[N + 1], v[N + 1];
bool sus[N + 1];
int lsp(string a, string b){
string s = "$" + b + "$" + a;
vector <int> kmp((int)s.size(), 0);
for(int i = 2; i < (int)s.size(); i++){
int l = kmp[i - 1];
while(l > 0 && s[l + 1] != s[i])
l = kmp[l];
if(s[l + 1] == s[i])
kmp[i] = l + 1;
}
return (int)b.size() - kmp[(int)s.size() - 1];
}
bool sussy(string a, string b){
string s = "$" + b + "$" + a;
vector <int> kmp((int)s.size(), 0);
for(int i = 2; i < (int)s.size(); i++){
int l = kmp[i - 1];
while(l > 0 && s[l + 1] != s[i])
l = kmp[l];
if(s[l + 1] == s[i])
kmp[i] = l + 1;
if(kmp[i] == (int)b.size())
return true;
}
return false;
}
void calcCost(){
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(i != j){
cost[i][j] = lsp(v[i], v[j]);
cost[j][i] = lsp(v[j], v[i]);
}
}
int dp[(1 << N)][N + 1], r[(1 << N)][N + 1];
vector <int> in[N + 1];
string HamiltonChain(){
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(i != j)
in[i].push_back(j);
for(int msk = 0; msk < (1 << n); msk++)
for(int i = 0; i < n; i++)
dp[msk][i] = inf;
for(int i = 0; i < n; i++)
dp[(1 << i)][i] = v[i].size();
for(int msk = 1; msk < (1 << n); msk++)
for(int i = 0; i < n; i++)
if(msk & (1 << i))
for(auto vec : in[i])
if(msk & (1 << vec))
if(dp[msk ^ (1 << i)][vec] + cost[vec][i] < dp[msk][i]){
dp[msk][i] = dp[msk ^ (1 << i)][vec] + cost[vec][i];
r[msk][i] = vec;
}
int cycLen = inf, last = 0;
for(int i = 0; i < n; i++)
if(dp[(1 << n) - 1][i] < cycLen)
cycLen = dp[(1 << n) - 1][i], last = i;
vector <int> sol;
sol.push_back(last);
int msk = (1 << n) - 1;
for(int i = 1; i < n; i++){
int aux = last;
last = r[msk][last];
msk -= (1 << aux);
sol.push_back(last);
}
reverse(sol.begin(), sol.end());
string ans = v[sol[0]];
for(int i = 1; i < (int)sol.size(); i++){
for(int j = (int)v[sol[i]].size() - cost[sol[i - 1]][sol[i]]; j < (int)v[sol[i]].size(); j++)
ans += v[sol[i]][j];
}
return ans;
}
int main(){
fin >> n;
for(int i = 0; i < n; i++)
fin >> vaux[i];
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
if(i != j && sussy(vaux[i], vaux[j]))
sus[j] = true;
int m = 0;
for(int i = 0; i < n; i++)
if(!sus[i])
v[m++] = vaux[i];
n = m;
calcCost();
fout << HamiltonChain() << '\n';
return 0;
}