Cod sursa(job #841155)

Utilizator stoicatheoFlirk Navok stoicatheo Data 23 decembrie 2012 20:44:56
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <fstream.h>
#include <string.h>
 
#define MAXS 30050
#define MAX 19
 
#define MAX2n 270000
 
int n;
char *sir[MAX];
int len[MAX];
 
int *pi[MAX];
 
int inclus[MAX];
int l[MAX][MAX];
 
int prec[MAX2n][MAX];
long opt[MAX2n][MAX];
 
long pow2[MAX];
 
long Back(long config, int last)
{
  if(prec[config][last]!=0)
   return opt[config][last];
  int i;
  long config2 = config ^ pow2[last];
  long optm = 0;
  prec[config][last] = -1;
  for(i=0;i<n;i++) if(i!=last)
   if( (config & pow2[i])!=0 )
    {
     long optc=Back(config2, i);
     if(optc + l[i][last] >= optm)
    {
      prec[config][last] = i+1;
      optm = optc + l[i][last];
    }
    }
  opt[config][last] = optm;
  return optm;
}
 
ifstream in("adn.in");
ofstream out("adn.out");
 
void Print(long config, int i)
{
 if(i<0) 
  return;
 long config2 = config ^ pow2[i];
 Print(config2, prec[config][i]-1);
 if(prec[config][i]<0)
  out<<sir[i];
 else
  out<<(sir[i]+l[prec[config][i]-1][i]);
}
 
int main()
{
 in>>n;
 int i,j;
 for(i=0;i<n;i++)
  { sir[i] = new char[MAXS]; pi[i] = new int[MAXS];
  in>>sir[i]; len[i]=strlen(sir[i]);}
 
 for(i=0;i<n;i++)
  {
   pi[i][0]=0;
   int k=0;
   for(j=1;j<len[i];j++)
    {
      while(k>0)
       {
         if(sir[i][j] != sir[i][k])
           k = pi[i][k-1];
         else
           break;
       }
      if(sir[i][j] == sir[i][k]) pi[i][j] = ++k;
      else pi[i][j] = 0;
    }
  }
  
 for(i=0;i<n;i++)
  for(j=0;j<n;j++) if(i!=j)
    {
     int k=0;
     int p;
     for(p=0;p<len[i];p++)
      {
    while(k>0)
         {
          if(sir[i][p] != sir[j][k])
            k = pi[j][k-1];
          else
            break;
         }
        if(sir[i][p] == sir[j][k]) ++k;
        else k = 0;
         
        if(k==len[j])
          {
       inclus[j] = 1;
           break;
          }
      }
     l[i][j] = k;
    }
 pow2[0]=1;
 for(i=1;i<=n;i++)
  pow2[i] = pow2[i-1]*2;
 long cfg = pow2[n]-1;
 for(i=0;i<n;i++) if(inclus[i])
   cfg ^= pow2[i];
 int optm = -1;
 int opti = 0;
 for(i=0;i<n;i++) if(!inclus[i])
  {
  long optt = Back(cfg,i);
  if(optt > optm)
   {
    optm = optt;
    opti = i;
   }
  }
 Print(cfg, opti);
 out<<"\n";
 return 0;
}