Cod sursa(job #266880)

Utilizator Sorin_IonutBYSorynyos Sorin_Ionut Data 26 februarie 2009 11:21:27
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 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;
     }