Pagini recente » Cod sursa (job #1125421) | Cod sursa (job #1464799) | Cod sursa (job #318356) | Cod sursa (job #493311) | Cod sursa (job #178615)
Cod sursa(job #178615)
#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,fin;
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])
{
el[q]=1;
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=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++)
if (el[i]==0)
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)&&(el[i]==0))
for (k=1;k<=n;k++)
if ((!(put[k-1]&j))&&(el[k]==0))
{
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;
}
}
}
//printf("%d\n",t[5][30]);
fin=put[n]-1;
for (i=1;i<=n;i++)
if (el[i]==1)
{
fin=fin&(put[n]-put[i-1]-1);
}
lr=1;
while (el[lr]==1)
lr++;
for (i=lr+1;i<=n;i++)
if (el[i]==0)
if (t[i][fin]<t[lr][fin])
lr=i;
i=0;
lj=fin;
while (lr!=0)
{
i++;
rez[i]=lr;
aux=lr;
lr=dui[aux][lj];
lj=duj[aux][lj];
}
n=i;
for (j=1;j<=l[rez[n]];j++)
printf("%c",v[rez[n]][j]);
n=i;
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]);
}
printf("\n");
return 0;
}