Cod sursa(job #1703570)

Utilizator Athena99Anghel Anca Athena99 Data 17 mai 2016 10:21:51
Problema ADN Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.73 kb
#include <fstream>
#include <string>

using namespace std;

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

const int nmax= 18;
const int lmax= 30001;
const int pmax= 1<<nmax;

bool u[nmax];
int p[lmax+1], c[nmax][nmax], d[pmax][nmax], sol[nmax];

string s[nmax];

void prefix( string a ) {
    p[0]= p[1]= 0;
    for ( int i= 2, k= 0; i<(int)a.size(); ++i ) {
        for ( ; k>0 && a[k+1]!=a[i]; k= p[k] ) ;
        if ( a[k+1]==a[i] ) {
            ++k;
        }
        p[i]= k;
    }
}

void f( int a1, int b1, string a, string b ) {
    for ( int i= 1, k= 0; i<(int)b.size(); ++i ) {
        for ( ; k>0 && a[k+1]!=b[i]; k= p[k] ) ;
        if ( a[k+1]==b[i] ) {
            ++k;
        }
        if ( i==(int)b.size()-1 ) {
            c[b1][a1]= k;
        }
        if ( k==(int)a.size()-1 ) {
            if ( (int)a.size()==(int)b.size() ) {
                u[min(a1, b1)]= 1;
            } else {
                u[a1]= 1;
            }
        }
    }
}

int main(  ) {
    int n;
    fin>>n;
    for ( int i= 0; i<n; ++i ) {
        s[i].push_back(' ');
        string aux;
        fin>>aux;
        for ( int j= 0; j<(int)aux.size(); ++j ) {
            s[i].push_back(aux[j]);
        }
    }

    for ( int i= 0; i<n; ++i ) {
        prefix(s[i]);
        for ( int j= 0; j<n; ++j ) {
            if ( i!=j ) {
                f(i, j, s[i], s[j]);
            }
        }
    }
    for ( int i= 0; i<n; ++i ) {
        if ( u[i]==1 ) {
            for ( int j= 0; j<n; ++j ) {
                c[i][j]= c[j][i]= 0;
            }
        }
    }

    for ( int i= 0; i<pmax; ++i ) {
        for ( int j= 0; j<n; ++j ) {
            if ( (i&(1<<j))!=0 ) {
                for ( int k= 0; k<n; ++k ) {
                    if ( k!=j && (i&(1<<k))!=0 ) {
                        d[i][j]= max(d[i][j], d[i-(1<<j)][k]+c[j][k]);
                    }
                }
            }
        }
    }

    sol[0]= -1;
    for ( int i= 0; i<n; ++i ) {
        if ( u[i]==0 && (sol[0]==-1 || d[(1<<n)-1][i]>d[(1<<n)-1][sol[0]]) ) {
            sol[0]= i;
        }
    }
    for ( int i= 1, j= (1<<n)-1; i<n; ++i ) {
        j= j-(1<<sol[i-1]);
        sol[i]= -1;
        for ( int k= 0; k<n; ++k ) {
            if ( u[k]==0 && (j&(1<<k))!=0 && (sol[i]==-1 || d[j][k]>d[j][sol[i]]) ) {
                sol[i]= k;
            }
        }
    }

    for ( int i= 1; i<(int)s[sol[0]].size(); ++i ) {
        fout<<s[sol[0]][i];
    }
    for ( int i= 1; i<n; ++i ) {
        if ( sol[i]!=-1 ) {
            for ( int j= c[sol[i-1]][sol[i]]+1; j<(int)s[sol[i]].size(); ++j ) {
                fout<<s[sol[i]][j];
            }
        }
    }
    fout<<"\n";

    return 0;
}