Cod sursa(job #1521192)

Utilizator ArchazeyBaltatu Andrei-Mircea Archazey Data 9 noiembrie 2015 23:54:29
Problema ADN Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
#include<bits/stdc++.h>
#define mp make_pair
#define PII pair<int,int>
#define fi first
#define se second
using namespace std;

ifstream fin("adn.in");
ofstream fout("adn.out");

const int NMAX=20;
const int XMAX=30005;
const int LIMIT=(1<<18)+5;

int n,len[NMAX],phi[NMAX][XMAX],phos[XMAX];
int mat[NMAX][NMAX],dp[LIMIT][NMAX],sol[NMAX];
char s[NMAX][XMAX],nxt[LIMIT][NMAX];

int main()
{
    int i,j,l,conf,dr,aux,kkt,mn;
    bool ok;
    fin>>n;
    for (i=1;i<=n;i++) {fin>>(s[i]+1);len[i]=strlen(s[i]+1);}
    for (i=1;i<=n;i++)
        for (j=2;j<=len[i];j++)
        {
            dr=phi[i][j-1];
            while (dr && s[i][dr+1]!=s[i][j]) dr=phi[i][dr];
            if (s[i][dr+1]==s[i][j]) dr++;
            phi[i][j]=dr;
        }
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
            if (i!=j)//i inaintea lui j
                {
                    ok=0;
                    for (l=1;l<=len[i];l++)
                    {
                        dr=phos[l-1];
                        while (dr && s[j][dr+1]!=s[i][l]) dr=phi[j][dr];
                        if (s[j][dr+1]==s[i][l]) dr++;
                        phos[l]=dr;
                        if (phos[l]==len[j]) ok=1;
                    }
                    if (ok==1) mat[i][j]=len[j];
                    else mat[i][j]=phos[len[i]];
                }

    for (conf=1;conf<(1<<n);conf++)
        for (i=0;i<n;i++)
            dp[conf][i]=1<<30;
    for (conf=1;conf<(1<<n);conf++)
        for (i=0;i<n;i++)//in ce se termina
            if (conf&(1<<i))
            {
                aux=conf-(1<<i);
                if (aux==0) {dp[conf][i]=len[i+1];continue;}
                for (j=0;j<n;j++)
                    if (aux&(1<<j))//in ce s-a terminat,si leg
                        {
                            kkt=dp[aux][j]+(len[i+1]-mat[j+1][i+1]);
                            if (kkt<dp[conf][i])
                            {
                                dp[conf][i]=kkt;
                                nxt[conf][i]=j;
                            }
                        }
            }
    //refacem solutia
    mn=1<<30;
    for (i=0;i<n;i++)
        if (dp[(1<<n)-1][i]<mn)
        {
            mn=dp[(1<<n)-1][i];
            aux=i;
        }
    kkt=aux;conf=(1<<n)-1;
    while (conf)
    {
        sol[++sol[0]]=kkt+1;
        aux=kkt;
        kkt=nxt[conf][kkt];
        conf-=1<<aux;
    }
    fout<<(s[sol[n]]+1);
    for (i=n-1;i>=1;i--)
        for (j=mat[sol[i+1]][sol[i]]+1;j<=len[sol[i]];j++)
            fout<<s[sol[i]][j];
    return 0;
}