Cod sursa(job #550100)

Utilizator EduardLEduard Luca EduardL Data 9 martie 2011 11:23:17
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 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; 
            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;
}