Cod sursa(job #1009223)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 12 octombrie 2013 17:47:47
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <fstream>
#include <cstring>
#include <bitset>

using namespace std;

char sir[20][30005];
int l[20];
int pref[20][30005];
int coresp[20][20];
int ram[20];
int din[262200][18];
int prec[262200][18];

#define INF 540200 //de mod

int minim(int a,int b)
{
    if(a<b)
        return a;
    return b;
}

ifstream cin("adn.in");
ofstream cout("adn.out");

inline void afis(int care,int cate)
{
    int i;
    for(i=cate;i<l[care];i++)
        cout<<sir[care][i];
}

int main()
{
    bitset<20> elimin;
    int n=0,i,k,j,p,poz=0;
    cin>>n;
    for(i=0;i<n;i++)
    {
        cin.get();
        cin.get(sir[i],30005);
        l[i]=strlen(sir[i]);
        k=0;
        pref[i][0]=0;
        for(j=1;j<l[i];j++)
        {
            while(k>0 && sir[i][j]!=sir[i][k])
                k=pref[i][k-1];
            if(sir[i][j]==sir[i][k])
                k++;
            pref[i][j]=k;
        }
    }
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            if(i!=j)
            {
                k=0;
                for(p=0;p<l[i];p++)
                {
                    while(k>0 && sir[i][p]!=sir[j][k])
                        k=pref[j][k-1];
                    if(sir[i][p]==sir[j][k])
                        k++;
                    if(k==l[j])
                    {
                        elimin[j]=1;
                        k=pref[j][k-1];
                        break;
                    }
                }
                coresp[i][j]=k;
            }
    for(i=0;i<n;i++)
        if(!elimin[i])
            ram[poz++]=i;
   int aux;
   prec[0][0]=-1;
    for(i=1;i<(1<<(poz));i++)
    {
        for(j=0;j<poz;j++)
        {
            din[i][j]=INF;
            prec[i][j]=-1;
            if(i&(1<<j))
                for(k=0;k<poz;k++)
                    if(((i&(1<<k))!=0))
                    {
                        aux=din[i^(1<<j)][k]-coresp[ram[k]][ram[j]]+l[ram[j]];
                        if(din[i][j]>aux)
                            din[i][j]=aux,prec[i][j]=k;
                    }
            if((i&(i-1))==0)
                prec[i][j]=-1;
        }
    }
    int rasp[20],poz2=0;
    int care=-1,mini=INF;
    for(i=0;i<poz;i++)
    {
        if(din[(1<<poz)-1][i]<mini)
            mini=din[(1<<poz)-1][i],care=i;
    }
    int stare=(1<<poz)-1,vechi=care;
    while(care>=0)
    {
        rasp[poz2++]=care;
        care=prec[stare][care];
        stare-=(1<<(vechi));
        vechi=care;
    }

    afis(ram[rasp[poz2-1]],0);
    for(i=poz2-2;i>=0;i--)
        afis(ram[rasp[i]],coresp[ram[rasp[i+1]]][ram[rasp[i]]]);
    cout<<'\n';

    cin.close();
    cout.close();
    return 0;
}