Cod sursa(job #1001639)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 25 septembrie 2013 18:37:19
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <fstream>
#include <vector>
#include <utility>

using namespace std;

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

string s[20],sol;

int m[20][20],pi[30001],series[20];
int hamilton[1<<18][18],hamiltonpath[1<<18][18];
int n;

void KMP (string s, int ind)
{
    int n = s.length();

    int k = -1;
    pi[0] = -1;

    for (int i=1; i<n; ++i)
    {
        while (k > -1 && s[k+1] != s[i]) k = pi[k];
        if (s[k+1]==s[i]) ++k;
        pi[i] = k;
    }
}

void draw_edge (int ind1, int ind2)
{
    int n1 = s[ind1].length();

    int k = -1,kmax=-1;

    for (int i=0; i<n1; ++i)
    {
        while (k > -1 && s[ind2][k+1] != s[ind1][i]) k = pi[k];
        if (s[ind2][k+1] == s[ind1][i]) ++k;
        if (k > kmax) kmax = k;
    }

    m[ind1][ind2] = kmax+1;
}

int main()
{
    fin>>n;

    for (int i=0; i<n; ++i)
    {
        fin>>s[i];
        KMP (s[i],i);
    }

    for (int i=0; i<n; ++i)
    {
        KMP (s[i],i);
        for (int j=0; j<n; ++j)
        {
            if (i!=j)
            draw_edge (j,i);
        }
    }

    int nr = (1<<n)-1;

    for (int i=0; i<=nr; ++i)
        for (int j=0; j<n; ++j)
        {
            hamilton[i][j]=-1;
            hamiltonpath[i][j]=-1;
        }

    for (int j=0; j<n; ++j)
    {
        hamilton[1<<j][j]=0;
        hamiltonpath[1<<j][j]=j;
    }

    for (int i=1; i<=nr; ++i)
    {
        for (int j=0; j<n; ++j)
        {
            if (hamilton[i][j]==-1) continue;
            for (int k=0; k<n; ++k)
            {
                if ((i | (1<<k))!=i)
                {
                    if (hamilton[i][j] + m[j][k] > hamilton [i | (1<<k)][k])
                        {
                            hamilton [i | (1<<k)][k] = hamilton[i][j] + m[j][k];
                            hamiltonpath [i | (1<<k)][k] = j;
                        }
                }
            }
        }
    }

    int i,j=0,maxv=0;

    for (i=0; i<n; ++i)
        if (hamilton[nr][i] > maxv)
        {
            maxv = hamilton[nr][i];
            j = i;
        }
    i = nr;
    int t=n;

    while (i)
    {
        series[--t] = j;
        int temp = j;
        j = hamiltonpath[i][temp];
        i = i-(1<<temp);
    }

    fout<<s[series[0]];

    for (int i=1; i<n; ++i)
    {
        int k = m[series[i-1]][series[i]];
        for (int j=k; j<s[series[i]].length(); ++j)
            fout<<s[series[i]][j];
    }
}