Pagini recente » Cod sursa (job #2604282) | Cod sursa (job #1222463) | Cod sursa (job #2692237) | Cod sursa (job #2839160) | Cod sursa (job #3197467)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
vector <string> adn(20, "");
int c[18][18];
int pi[60005];
int dp[(1 << 18)][18];
int last[(1 << 18)][18];
void kmp(int s1, int s2){
int n,i,k = 0;
string s = adn[s1] + adn[s2];
pi[0] = 0;
n = s.size();
for(i = 1; i < n; i++){
while(k > 0 && s[i] != s[k]) k = pi[k - 1];
if(s[i] == s[k]) k++;
pi[i] = k;
}
int m = min(adn[s1].size(), adn[s2].size());
while(k > m) k = pi[k - 1];
c[s2][s1] = k;
}
bool fnd(string s1, string s2){
int i,k = 0,p = s1.size(), n = s2.size();
pi[0] = 0;
for(i = 1; i < p; i++){
while(k > 0 && s1[i] != s1[k]) k = pi[k - 1];
if(s1[k] == s1[i]) k++;
pi[i] = k;
}
k = 0;
for(i = 0; i < n; i++){
while(k > 0 && s1[k] != s2[i]) k = pi[k - 1];
if(s1[k] == s2[i]) k++;
if(k == p) return 1;
}
return 0;
}
bool comp(const string &a, const string &b){
return a.size() < b.size();
}
vector <int> sol;
vector <int> dl;
int main()
{
int n,i,k,j,rez = 0x3f3f3f3f,t;
fin >> n;
for(i = 0; i < n; i++){
fin.get();
fin >> adn[i];
}
adn.resize(n);
sort(adn.begin(), adn.end(), comp);
for(i = 0; i < n; i++){
for(j = i + 1; j < n; j++){
if(fnd(adn[i], adn[j])){
dl.push_back(i);
break;
}
}
}
reverse(dl.begin(), dl.end());
for(auto x : dl){
n--;
adn.erase(adn.begin() + x);
}
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
if(i == j) continue;
kmp(i,j);
}
}
memset(dp,0x3f,sizeof dp);
for(i = 0; i < n; i++) dp[(1 << i)][i] = adn[i].size();
for(k = 1; k < (1 << n); k++){
for(i = 0; i < n; i++) if((1 << i) & k){
for(j = 0; j < n; j++){
if(i != j && (1 << j) & k){
if(dp[k][i] > dp[k ^ (1 << i)][j] + adn[i].size() - c[j][i]){
dp[k][i] = dp[k ^ (1 << i)][j] + adn[i].size() - c[j][i];
last[k][i] = j;
}
}
}
}
}
for(i = 0; i <= n; i++){
if(rez > dp[(1 << n) - 1][i]){
rez = dp[(1 << n) - 1][i];
t = i;
}
}
k = (1 << n) - 1;
for(i = n; i > 0; i--){
int lt = t;
sol.push_back(t);
t = last[k][t];
k ^= (1 << lt);
}
reverse(sol.begin(), sol.end());
fout << adn[sol[0]];
for(i = 1; i < sol.size(); i++){
for(j = c[sol[i - 1]][sol[i]]; j < adn[sol[i]].size(); j++) fout << adn[sol[i]][j];
}
return 0;
}