Cod sursa(job #480552)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 28 august 2010 16:05:46
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.87 kb
#include <stdio.h>
#include <string.h>
#define Nmax 19
#define Lgsir 30002

char s[Nmax][Lgsir];
int pi[Lgsir];
int A[1<<18][Nmax],Next[1<<18][Nmax];
int nw[Nmax],old[Nmax],este[Nmax],lg[Nmax];
int p[Nmax][Nmax], p2[Nmax][Nmax];
int n;

inline int Maxim(int x,int y){ return x>y ? x:y; }

void prefix(int wh){
	int i,k=-1;
	pi[0]=-1;
	for(i=1;i<lg[wh];++i){
		while( k!=-1 && s[wh][k+1] != s[wh][i] )
			k=pi[k];
		if( s[wh][k+1] == s[wh][i] ) k++;
		pi[i]=k;
	}
}
void potriviri(int wh1,int wh2){
	int i,k=0;
	for(i=0;i<lg[wh2];++i){
		while(k!=-1 && s[wh1][k+1] != s[wh2][i] )
			k=pi[k];
		if( s[wh1][k+1] == s[wh2][i] ) k++;
		if( k == lg[wh1]-1 ){ este[wh1]=0; break;} // inghite
	}
	if( i==lg[wh2] ) p[wh1][wh2]=k;
}

int main(){
	int i,j,c,vali,q,com,start,mx=0;
	freopen("adn.in","r",stdin);
	freopen("adn.out","w",stdout);
	scanf("%d\n",&n);
	for(i=1;i<=n;++i){
		scanf("%s",s[i]);
		lg[i]=strlen(s[i]);
	}
	
	for(i=1;i<=n;++i){
		prefix(i); este[i]=1;
		for(j=1;j<=n && este[i];++j)
			if(i!=j) potriviri(i,j);
	}
	
	for(vali=0,i=1;i<=n;++i)
		if( este[i] ){
			nw[i]=++vali; // assign new values 4 words
			old[vali]=i;
		}
	
	for(i=1;i<=n;++i)
		if( este[i] )
		for(j=1;j<=n;++j)
			if( i!=j && este[j] )
				p2[nw[i]][nw[j]]=p[i][j]+1;
	
	n=vali;
	for(c=1;c<(1<<n);++c)
		for(i=0;i<n;++i)
			if( (c&(1<<i)) == 0 )
				for(j=0; j<n; ++j)
					if( (c&(1<<j)) )
						if(A[c][i+1] < p2[j+1][i+1]+A[c-(1<<j)][j+1]){
							A[c][i+1] = p2[j+1][i+1]+A[c-(1<<j)][j+1];
							Next[c][i+1]=j+1;
						}
	
	for(i=1;i<=n;++i)
		if( A[(1<<n)-1-(1<<(i-1))][i] > mx ) mx=A[(1<<n)-1-(1<<(i-1))][i], start=i;
	
	for(i=start,c=(1<<n)-1; i; ){
		c-=(1<<(i-1));
		j=Next[c][i];
		com=p2[j][i];
		for(q=0;q<lg[old[i]]-com;++q) printf("%c",s[old[i]][q]);
		i=j;
	}
	
	//printf("\n");
	fclose(stdin); fclose(stdout);
	return 0;
}