Pagini recente » Cod sursa (job #312568) | Cod sursa (job #3162) | Cod sursa (job #133433) | Cod sursa (job #2851845) | Cod sursa (job #2646475)
#include <bits/stdc++.h>
using namespace std;
#define NMAX 20
#define LMAX 30004
int n, pr[LMAX], m[NMAX][NMAX], DP[(1<<18) + 10][20], ant[(1<<18) + 10][20];
string s[NMAX];
int kmpLast(string A, string B){
swap(A,B);
int k = 0;
for (int i=2;i<A.size();i++){
while (k && A[k+1] != A[i]) k = pr[k];
if (A[i] == A[k+1]) k++;
pr[i] = k;
}
k = 0;
for (int i=1;i<B.size();i++){
while (k && A[k+1] != B[i]) k = pr[k];
if (B[i] == A[k+1]) k++;
if (k+1 >= A.size()){
return A.size();
}
}
return k;
}
void reconst(int cfg, int lst){
if(__builtin_popcount(cfg) == 1){
if (s[lst+1].size() > 1)
cout << s[lst+1].substr(1);
return;
}
int antLst = ant[cfg][lst];
reconst(cfg ^ (1<<lst), antLst);
for (int i=m[antLst+1][lst+1]+1;i<s[lst+1].size();i++) cout << s[lst+1][i];
}
int main()
{
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
cin >> n;
for (int i=1;i<=n;i++){
cin >> s[i];
s[i] = " " + s[i];
}
for (int tt=1;tt<=2;tt++)
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (i==j) continue;
m[i][j] = kmpLast(s[i], s[j]);
if(m[i][j] == s[j].size()){
s[j] = "";
}
}
}
int mx = 1<<n;
memset(DP,0x3f,sizeof(DP));
for (int i=1;i<mx;i++){
for (int j=0;j<n;j++){
if (!(i & (1<<j))) continue;
if (__builtin_popcount(i) == 1){
DP[i][j] = s[j+1].size();
}
for (int k=0;k<n;k++){
if (i & (1<<k)) continue;
int newV = DP[i][j] + s[k+1].size() - m[j+1][k+1];
if (DP[i ^ (1<<k)][k] > newV){
DP[i ^ (1<<k)][k] = newV;
ant[i ^ (1<<k)][k] = j;
}
}
}
}
int mn = 1e9, sav = -1;
for (int i=0;i<n;i++){
if (DP[mx-1][i] < mn){
mn = DP[mx-1][i];
sav = i;
}
}
reconst(mx-1, sav);
return 0;
}