Cod sursa(job #1226521)

Utilizator RaduGabriel2012Dinu Radu RaduGabriel2012 Data 5 septembrie 2014 21:13:05
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
ifstream f("adn.in");
ofstream g("adn.out");
 char s[19][30005];
 int n,nw,pr[30005],use[20][20],ok[20],dp[(1<<18)][19],last[(1<<18)][19],eq[20],ln[20];
 int inf=2147000000,res[20],conf,act,nr;

 void Kmp(int x,int y)
 { int i,j,l1=strlen(s[x]+1),l2=strlen(s[y]+1),k=0;

        memset(pr,0,sizeof(pr));

    for(i=2;i<=l2;i++)
     {
         while(s[y][k+1]!=s[y][i] && k)
          k=pr[k];

      if (s[y][k+1]==s[y][i]) {k++; pr[i]=k;}
       else pr[i]=0;
     }

      k=0;
    for(i=1;i<=l1;i++)
     {
         while(s[x][i]!=s[y][k+1] && k)
          k=pr[k];

       if (s[x][i]==s[y][k+1]) k++;
        else pr[i]=0;

        if (k==l2) ok[y]=1;
     }

   use[x][y]=k;
 }

int main()
{ int i,j,t,sol;
    f>>n;

    for(i=1;i<=n;i++)
     f>>s[i]+1;

    for(i=1;i<=n;i++)
     for(j=i+1;j<=n;j++)
      {Kmp(i,j);
       Kmp(j,i);}

     for(i=1;i<=n;i++)
      if (!ok[i])
      {nw++;
      eq[nw]=i;
      ln[nw]=strlen(s[i]+1); }

    for(i=0;i<(1<<nw);i++)
     for(j=1;j<=nw;j++)
      dp[i][j]=inf;

    for(i=1;i<=nw;i++)
     {dp[1<<(i-1)][i]=ln[i];
      last[1<<(i-1)][i]=0;
     }
   for(i=1;i<(1<<nw);i++)
    for(j=1;j<=nw;j++)
     {

         if (i&(1<<(j-1))  && dp[i][j]!=inf)
      {
         for(t=1;t<=nw;t++)
          if ( (!(i&(1<<(t-1)))) && t!=j )
           {if (dp[i+(1<<(t-1))][t]>dp[i][j]+ln[t]-use[eq[j]][eq[t]])
               {dp[i+(1<<(t-1))][t]=dp[i][j]+ln[t]-use[eq[j]][eq[t]];
                 last[i+(1<<(t-1))][t]=j;
               }
           }

      }

     }


    sol=inf;

    for(j=1;j<=nw;j++)
     { //cout<<dp[(1<<nw)-1][j]<<"\n";
         if (sol>dp[(1<<nw)-1][j])
        {sol=dp[(1<<nw)-1][j];
         act=j;
        }
     }
     conf=(1<<nw)-1; nr=nw; res[nr]=act; nr--;

     while(nr)
     { conf-=(1<<(act-1));
         act=last[conf+(1<<(act-1))][act];
        res[nr]=act; nr--;
     }

     for(i=1;i<=nw;i++)
      for(j=1;j<=ln[res[i]]-use[eq[res[i]]][eq[res[i+1]]];j++)
        g<<s[eq[res[i]]][j];

    return 0;
}