Pagini recente » Cod sursa (job #3348667) | Cod sursa (job #62659) | Cod sursa (job #3306478) | Cod sursa (job #3312835) | Cod sursa (job #3327191)
#include <fstream>
#include <cstring>
#define nmax 19
#define dim 30001
#define inf 1e9
using namespace std;
ifstream cin("adn.in");
ofstream cout("adn.out");
int n,lps[2*dim],cost[nmax][nmax],dp[nmax][(1<<nmax)],t[nmax][(1<<nmax)];
bool in[nmax];
string s[nmax];
void get_lps(string s){
int len=0,i=1,n=s.size();
while(i<n){
if(s[i]==s[len]){
len++;
lps[i++]=len;
}else if(len==0)
lps[i++]=0;
else
len=lps[len-1];
}
}
bool verif(int k1,int k2){
int len=0,i=0,n=s[k1].size(),m=s[k2].size();
if(n>m)
return 0;
while(i<m){
if(s[k1][len]==s[k2][i]){
len++;
i++;
}else if(len==0)
i++;
else
len=lps[len-1];
if(len==n)
return 1;
}
return 0;
}
void new_words(){
int k=0;
for(int i=1;i<=n;i++)
if(in[i])
s[++k]=s[i];
n=k;
}
void rec(int nod,int mask){
int start=0;
if(t[nod][mask]!=0){
rec(t[nod][mask],mask-(1<<(nod-1)));
start=cost[t[nod][mask]][nod];
}
for(int i=start;s[nod][i]!=0;i++)
cout<<s[nod][i];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>s[i];
in[i]=1;
}
for(int i=1;i<=n;i++)
if(in[i]){
get_lps(s[i]);
for(int j=1;j<=n;j++)
if(i!=j&&in[j]&&verif(i,j)){
in[i]=0;
break;
}
}
new_words();
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
if(i!=j){
get_lps(s[i]+s[j]);
cost[j][i]=lps[s[i].size()+s[j].size()-1];
}
}
for(int mask=1;mask<(1<<n);mask++)
for(int i=0;i<n;i++)
dp[i+1][mask]=inf;
for(int i=0;i<n;i++)
dp[i+1][(1<<i)]=s[i+1].size();
for(int mask=1;mask<(1<<n);mask++){
for(int i=0;i<n;i++)
if((mask>>i)&1){
for(int j=0;j<n;j++)
if(i!=j&&!((mask>>j)&1)){
int next=mask+(1<<j);
if(dp[j+1][next]>dp[i+1][mask]+s[j+1].size()-cost[i+1][j+1]){
dp[j+1][next]=dp[i+1][mask]+s[j+1].size()-cost[i+1][j+1];
t[j+1][next]=i+1;
}
}
}
}
int last=1;
for(int i=2;i<=n;i++)
if(dp[last][(1<<n)-1]>dp[i][(1<<n)-1])
last=i;
rec(last,(1<<n)-1);
return 0;
}