Pagini recente » Cod sursa (job #2338686) | Cod sursa (job #181820) | Cod sursa (job #1740994) | Cod sursa (job #658337) | Cod sursa (job #1990050)
#include <cstdio>
#include <cstring>
#include <stack>
#include <bitset>
using namespace std;
FILE *f=fopen("adn.in","r");
FILE *g=fopen("adn.out","w");
int cst[20][20];
char rez[600005];
int ind;
int N;
char C[20][30005];
int dp[1<<18][19];
int ant[1<<18][19];
int L[20];
int F[30005];
bool inc;
int K;
int kmp(int a,int b)
{
inc=0;
F[1]=0;
for(int i=2;i<=L[b];i++)
{
int k=F[i-1];
while(k&&C[b][k+1]!=C[b][i])k=F[k];
if(C[b][k+1]==C[b][i])k++;
F[i]=k;
}
int j=0;
for(int i=1;i<=L[a];i++)
{
while(j&&C[b][j+1]!=C[a][i])j=F[j];
if(C[b][j+1]==C[a][i])j++;
if(j==L[b])
{
j=F[j];
inc=1;
return 0;
}
}
return j;
}
stack<int> S;
bitset<20>nok;
void solve()
{
for(int i=1;i<=N;i++)
for(int j=0;j<=N;j++)
cst[i][j]=1<<20;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
if(i!=j)
{
cst[i][j]=kmp(i,j);
if(inc&&(K&(1<<(j-1)))&&(K&(1<<(i-1))))
K^=(1<<(j-1));
}
for(int i=1;i<=N;i++)dp[0][i]=1<<20;
dp[0][0]=0;
for(int i=1;i<=K;i++)
{
dp[i][0]=1<<20;
for(int j=1;j<=N;j++)
{
dp[i][j]=1<<20;
if(i&(1<<(j-1)))
{
for(int k=0;k<=N;k++)
if((k==0||(k!=j&&(i&(1<<(k-1)))))&&dp[i][j]>dp[i^(1<<(j-1))][k]+(L[j]-cst[k][j]))
{
dp[i][j]=dp[i^(1<<(j-1))][k]+(L[j]-cst[k][j]);
ant[i][j]=k;
}
}
}
}
int imin=0;
for(int i=1;i<=N;i++)
if(dp[K][i]<dp[K][imin])imin=i;
int conf=K;
while(conf)
{
S.push(imin);
conf^=(1<<(imin-1));
imin=ant[conf^(1<<(imin-1))][imin];
}
int pr=0;
while(!S.empty())
{
for(int i=cst[pr][S.top()]+1;i<=L[S.top()];i++)
rez[ind++]=C[S.top()][i];
pr=S.top();
S.pop();
}
}
int main()
{
fscanf(f,"%d\n",&N);
K=(1<<N)-1;
for(int i=1;i<=N;i++){fgets(C[i]+1,30001,f);L[i]=strlen(C[i]+1);L[i]-=(C[i][L[i]]=='\n');}
solve();
fputs(rez,g);
fclose(f);
fclose(g);
return 0;
}