Pagini recente » Cod sursa (job #28846) | Cod sursa (job #752837) | Cod sursa (job #651621) | Cod sursa (job #223810) | Cod sursa (job #1008759)
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_N=18;
const int MAX_L=30100;
const int INF=1000000;
int from[300000][MAX_N];
int d[300000][MAX_N];
int c[MAX_N][MAX_N];
char a[MAX_N][MAX_L];
int pi[MAX_N][MAX_L];
int sz[MAX_N];
void prefix(const char s[MAX_L],int pi[MAX_L],int n) {
pi[1]=0;
int p=0;
for(int i=2;i<=n;i++) {
while(p&&s[i]!=s[p+1]) {
p=pi[p];
}
if(s[i]==s[p+1]) {
p++;
}
pi[i]=p;
}
}
int kmp(int x,int y) {
int p=0;
for(int i=1;i<=sz[x];i++) { //cel mai lung prefix din y al sirului x[1..i]
while(p&&a[x][i]!=a[y][p+1]) {
p=pi[y][p];
}
if(a[x][i]==a[y][p+1]) {
p++;
}
if(p==sz[y]) {
return p;
}
}
return p;
}
void afisare(int m,int p) {
fprintf(stderr,"%d %d\n",p,m);
int nm=m-(1<<p);
if(from[m][p]==-1) {
printf("%s",a[p]+1);
return;
}
afisare(nm,from[m][p]);
for(int i=c[from[m][p]][p]+1;i<=sz[p];i++) {
printf("%c",a[p][i]);
}
}
int main() {
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) {
scanf(" %s ",a[i]+1);
sz[i]=strlen(a[i]+1);
prefix(a[i],pi[i],sz[i]);
}
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
c[i][j]=kmp(i,j);
}
}
for(int i=0;i<(1<<n);i++) {
for(int j=0;j<n;j++) {
d[i][j]=INF;
from[i][j]=-1;
}
}
for(int i=0;i<n;i++) {
d[(1<<i)][i]=sz[i];
from[(1<<i)][i]=-1;
}
for(int i=1;i<(1<<n);i++) {
for(int j=0;j<n;j++) {
if(i&(1<<j)) {
for(int b=0;b<n;b++) {
if( !(i&(1<<b)) ) {
int ni=i|(1<<b);
int cst=d[i][j]+sz[b]-c[j][b];
if(cst<d[ni][b]) {
d[ni][b]=cst;
from[ni][b]=j;
}
//if(c[j][b]==sz[b]) {
// if(cst<d[ni][j]) {
// d[ni][j]=cst;
// from[ni][j]=j;
// }
//}
}
}
}
}
}
int ans=INF;
int poz;
for(int i=0;i<n;i++) {
if(d[(1<<n)-1][i]<ans) {
ans=d[(1<<n)-1][i];
poz=i;
}
}
afisare((1<<n)-1,poz);
return 0;
}