Cod sursa(job #287312)

Utilizator flamecataCiobanu Alexandru-Catalin flamecata Data 24 martie 2009 18:17:52
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.9 kb
# include <stdio.h>   
# include <string>   
  
using namespace std;   
  
# define FIN "adn.in"   
# define FOUT "adn.out"   
# define MAXL 30001   
# define MAXN 20   
# define MAXM 1<<18   
  
int N,i,j,k,maxq,mn,mx,f;   
int Prefix[MAXL];   
int C[MAXN][MAXN];   
int D[MAXN][MAXM];   
int U[MAXN][MAXM];   
char s[MAXN][MAXL];   
  
     void prefix(int p)   
     {   
       int i,k,L;   
          
       Prefix[0] = Prefix[1] = k = 0;   
       L = strlen(s[p]+1);   
          
       for (i = 2; i <= L; ++i)   
         {   
            while (k > 0 && s[p][i] != s[p][k+1])   
              k = Prefix[k];   
            if (s[p][i] == s[p][k+1])   
              k++;   
            Prefix[i] = k;   
         }   
     }   
        
     int KMP(int p,int r)   
     {   
        int L,l,i,k;   
           
        L = strlen(s[p]+1);   
        l = strlen(s[r]+1);   
           
        k = 0;   
        for (i = 1; i <= l; ++i)   
          {   
             while (k > 0 && s[p][k+1] != s[r][i])   
               k = Prefix[k];   
             if (s[p][k+1] == s[r][i])   
               k++;   
             if (k == L) return -1;   
          }   
        return k;   
     }   
  
     int main()   
     {   
         freopen(FIN,"r",stdin);   
         freopen(FOUT,"w",stdout);   
            
         scanf("%d\n",&N);   
         for (i = 1; i <= N; ++i)   
           gets(s[i]+1);   
              
         for (i = 1; i <= N; ++i)   
           for (j = 1; j <= N; ++j)   
             if (i != j)   
               {   
                  prefix(j);   
                  C[i][j] = KMP(j,i);   
                  if (C[i][j] == -1) mn|=(1<<(j-1));   
               }   
         maxq = 1 << N;   
         for (i = 1; i < maxq; ++i)   
           for (j = 1; j <= N; ++j)   
             if (!((1<<(j-1))&i))   
               {   
                 D[j][i] = -1;   
                 for (k = 1; k <= N; ++k)   
                   if ((1<<(k-1))&i)   
                     if (D[k][i-(1<<(k-1))]+C[j][k]>D[j][i])   
                       {   
                          D[j][i]=D[k][i-(1<<(k-1))]+C[j][k];   
                          U[j][i]=k;   
                       }   
               }   
            
         mx = -1; maxq -= 1+mn;   
         for (i = 1; i <= N; ++i)   
           if (D[i][maxq-(1<<(i-1))]>mx)   
             {   
                mx = D[i][maxq-(1<<(i-1))];   
                f = i;   
             }   
         printf("%s",s[f]+1);   
         maxq -= (1<<(f-1));   
         while (maxq > 0)   
           {   
              i = U[f][maxq];   
              mn = strlen(s[i]+1);   
              for (j = C[f][i]+1; j <= mn; ++j)   
                printf("%c",s[i][j]);   
              maxq-=(1<<(i-1));   
              f = i;   
           }   
            
         return 0;   
     }