Pagini recente » Cod sursa (job #593892) | Cod sursa (job #1077931) | Cod sursa (job #1578864) | Cod sursa (job #887866) | Cod sursa (job #178567)
Cod sursa(job #178567)
#include <cstdio>
#include <string.h>
#define inf 2147483647
using namespace std;
char v[20][30100];
long n,i,j,x[20][20],l[20],pi[30100],el[20],k,p,put[20],lr,lj,aux;
long t[20][1<<18],dui[20][1<<18],duj[20][1<<18],rez[20];
inline long min(long a, long b)
{
if (a<b)
return a;
else
return b;
}
void prefix(long q)
{
long x,i,j;
memset(pi,0,sizeof(pi));
pi[0]=-1;
pi[1]=0;
for (i=2;i<=l[q];i++)
{
x=pi[i-1];
if (v[q][x+1]==v[q][i])
pi[i]=x+1;
else
{
while (x>=0)
{
x=pi[x];
if (x<0)
break;
if (v[q][x+1]==v[q][i])
{
pi[i]=x+1;
break;
}
}
}
}
}
long KMP(long p, long q)
{
prefix(q);
long x,i,j;
x=0;
for (i=1;i<=l[p];i++)
{
if (v[p][i]==v[q][x+1])
x++;
else
{
while (x>=0)
{
x=pi[x];
if (x<0)
break;
if (v[p][i]==v[q][x+1])
{
x++;
break;
}
}
}
if (x<0)
x=0;
if (x==l[q])
return x;
}
return x;
}
int main(){
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
scanf("%d",&n);
for (i=0;i<=20;i++)
put[i]=1<<i;
for (i=1;i<=n;i++)
{
scanf("%s",v[i]);
l[i]=strlen(v[i]);
for (j=l[i];j>=1;j--)
v[i][j]=v[i][j-1];
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (i!=j)
{
x[i][j]=KMP(i,j);
/* if (x[i][j]==l[i])
el[i]=1;
if (x[i][j]==l[j])
el[j]=1;*/
}
for (i=n;i>=1;i--)
if (el[i]==1)
{
n--;
for (j=i;j<=n;j++)
for (k=1;k<=30000;k++)
v[j][k]=v[j+1][k];
}
/*for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%d ",x[i][j]);
printf("\n");
} */
//dinamica pe configuratii in 2^n*n^2
//t[i][j]=costul minim daca ultimu pus este i si am configuratia j
for (i=0;i<=put[n];i++)
for (j=0;j<=n;j++)
t[j][i]=inf;
for (i=1;i<=n;i++)
t[i][put[i-1]]=l[i];
for (j=1;j<=put[n];++j)
{
for (i=1;i<=n;i++)
//verific daca am i-ul in configuratia curenta
if (put[i-1]&j)
for (k=1;k<=n;k++)
if (!(put[k-1]&j))
{
if ((t[i][j]+l[k]-x[i][k])<t[k][j|put[k-1]])
{
t[k][j|put[k-1]]=t[i][j]+l[k]-x[i][k];
dui[k][j|put[k-1]]=i;
duj[k][j|put[k-1]]=j;
}
}
}
lr=1;
for (i=2;i<=n;i++)
if (t[i][(put[n])-1]<t[lr][put[n]-1])
lr=i;
i=0;
lj=put[n]-1;
while (lr!=0)
{
i++;
rez[i]=lr;
aux=lr;
lr=dui[aux][lj];
lj=duj[aux][lj];
}
for (j=1;j<=l[rez[n]];j++)
printf("%c",v[rez[n]][j]);
for (i=n;i>1;i--)
{
for (j=x[rez[i]][rez[i-1]]+1;j<=l[rez[i-1]];j++)
printf("%c",v[rez[i-1]][j]);
}
return 0;
}