Pagini recente » Cod sursa (job #3282344) | Cod sursa (job #3201311) | Statistici Nicu Robert Cristian (Robert_Nicu) | Monitorul de evaluare | Cod sursa (job #2987745)
//Ilie Dumitru
#include<cstdio>
#include<cstring>
#include<algorithm>
const int NMAX=20;
const int LENMAX=30005;
int N, len[NMAX];
char s[NMAX][LENMAX];
int prefix[NMAX][LENMAX];
int combine[NMAX][NMAX];
int index[NMAX];
int parent[1<<NMAX][NMAX];
int dp[1<<NMAX][NMAX];
void genPrefix(int n)
{
int i, q=0;
for(i=1;i<=len[n];++i)
{
while(q && s[n][q]!=s[n][i])
q=prefix[n][q];
prefix[n][i]=q;
if(q==0 || s[n][q]==s[n][i])
++q;
}
}
bool cmp(int i, int j)
{
return len[i]<len[j];
}
int getExtra(int a, int b)
{
int i, q=0;
for(i=1;i<=len[b];++i)
{
if(q==len[a])
return -1;
while(q && s[a][q+1]!=s[b][i])
q=prefix[a][q];
if(s[a][q+1]==s[b][i])
++q;
}
if(q==len[a])
return -1;
return len[a]-q;
}
void printSolution(int mask, int last, FILE* g)
{
if(last!=-1)
{
printSolution(mask^(1<<last), parent[mask][last], g);
int extra=parent[mask][last]==-1?len[index[last]]:dp[mask][last]-dp[mask^(1<<last)][parent[mask][last]];
fprintf(g, "%s", s[index[last]]+len[index[last]]-extra+1);
}
}
int main()
{
FILE* f=fopen("adn.in", "r"), *g=fopen("adn.out", "w");
int i, j, x, mask, min;
fscanf(f, "%d", &N);
fgets(s[0], LENMAX, f);
for(i=0;i<N;++i)
{
fgets(s[i]+1, LENMAX, f);
len[i]=strlen(s[i]+1);
index[i]=i;
if(s[i][len[i]]=='\n')
s[i][len[i]--]=0;
genPrefix(i);
}
std::sort(index, index+N, cmp);
for(i=0;i<N;++i)
{
for(j=i+1;j<N && index[i]!=-1;++j)
{
x=getExtra(index[i], index[j]);
if(x==-1)
index[i]=-1;
else
combine[index[j]][index[i]]=x;
}
if(index[i]==-1)
{
for(j=i+1;j<N;++j)
index[j-1]=index[j];
--i;
--N;
}
}
for(i=1;i<N;++i)
for(j=0;j<i;++j)
combine[index[j]][index[i]]=getExtra(index[i], index[j]);
for(i=(1<<N)-1;i;--i)
{
for(j=0;j<N;++j)
{
dp[i][j]=NMAX*LENMAX;
parent[i][j]=-1;
}
}
for(i=0;i<N;++i)
dp[1<<i][i]=len[index[i]];
for(mask=1;mask<(1<<N);++mask)
{
for(i=0;i<N;++i)
{
if(mask&(1<<i))
{
for(j=0;j<N;++j)
{
if((mask&(1<<j))==0)
{
//avem bit-ul i setat si bit-ul j nesetat
if(dp[mask|(1<<j)][j]>dp[mask][i]+combine[index[i]][index[j]])
{
dp[mask|(1<<j)][j]=dp[mask][i]+combine[index[i]][index[j]];
parent[mask|(1<<j)][j]=i;
}
}
}
}
}
}
min=0;
mask=(1<<N)-1;
for(i=1;i<N;++i)
{
if(dp[mask][min]>dp[mask][i])
min=i;
}
printSolution(mask, min, g);
fclose(f);
fclose(g);
return 0;
}