Cod sursa(job #2221434)

Utilizator patcasrarespatcas rares danut patcasrares Data 14 iulie 2018 12:25:36
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.04 kb
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<queue>
#define DN 30005
#define x first
#define y second
#define pb push_back
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
int n,nr,pr[DN],p,k,c[DN],dp[21][(1<<18)],d[19],f,mi=1e9;
pair<int,pair<int,int> >pr2[21][(1<<18)];
char b[21][DN],a[21][DN];
vector<pair<int,int> >v[21];
void ve(int nod,int conf)
{
    if(conf==0)
        return;
    ve(pr2[nod][conf].y.x,pr2[nod][conf].y.y);
    for(int i=d[nod]-pr2[nod][conf].x+1;i<=d[nod];i++)
        fout<<a[nod][i];
}
int main()
{
    fin>>n;
    for(int i=0;i<=n;i++)
    {
        fin.getline(b[i]+1,DN);
        c[i]=strlen(b[i]+1);
    }
    for(int i=1;i<=n;i++)
    {
        p=1;
        k=0;
        for(int h=2;h<=c[i];h++)
        {
            while(k&&b[i][k+1]!=b[i][h])
                k=pr[k];
            if(b[i][k+1]==b[i][h])
                k++;
            pr[h]=k;
        }
        for(int j=1;j<=n&&p;j++)
            if(i!=j)
            {
                k=0;
                for(int h=1;h<=c[j];h++)
                {
                    while(k&&b[i][k+1]!=b[j][h])
                        k=pr[k];
                    if(b[i][k+1]==b[j][h])
                        k++;
                    if(k==c[i])
                    {
                        p=0;
                        break;
                    }
                }
            }
        if(p)
        {
            nr++;
            strcpy(a[nr]+1,b[i]+1);
            d[nr]=c[i];
        }
    }
    n=nr;
    for(int i=1;i<=n;i++)
    {
        p=1;
        k=0;
        for(int h=2;h<=d[i];h++)
        {
            while(k&&a[i][k+1]!=a[i][h])
                k=pr[k];
            if(a[i][k+1]==a[i][h])
                k++;
            pr[h]=k;
        }
        for(int j=1;j<=n&&p;j++)
            if(i!=j)
            {
                k=0;
                for(int h=1;h<=d[j];h++)
                {
                    while(k&&a[i][k+1]!=a[j][h])
                        k=pr[k];
                    if(a[i][k+1]==a[j][h])
                        k++;
                }
                v[j].pb({i,d[i]-k});
            }
    }
    p=(1<<n);
    for(int i=1;i<=n;i++)
        for(int j=0;j<p;j++)
            dp[i][j]=1e9;
    for(int i=1;i<=n;i++)
        dp[i][(1<<(i-1))]=pr2[i][(1<<(i-1))].x=d[i];
    for(int i=1;i<p;i++)
        for(int j=1;j<=n;j++)
            if(dp[j][i])
                for(auto h:v[j])
                    if(!(i&(1<<(h.x-1))))
                    {
                        f=(i|(1<<(h.x-1)));
                        if(dp[j][i]+h.y<dp[h.x][f])
                        {
                            dp[h.x][f]=dp[j][i]+h.y;
                            pr2[h.x][f]={h.y,{j,i}};
                        }
                    }
    for(int i=1;i<=n;i++)
        mi=min(mi,dp[i][p-1]);
    for(int i=1;i<=n;i++)
        if(dp[i][p-1]==mi)
        {
            ve(i,p-1);
            break;
        }
}