Cod sursa(job #2538394)

Utilizator RedXtreme45Catalin RedXtreme45 Data 4 februarie 2020 18:29:25
Problema ADN Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.91 kb
#include <fstream>
#include <vector>
#include <cstring>
#define Nmax 19
#define Mmax 30001
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
int n,m,stare[Mmax],marime[Nmax],dp[270001][Nmax],max1,venire[270001][Nmax],ret;
bool elim[Nmax];
vector <string> s;
struct NodCost{
    int nod,cost;
};
vector <NodCost> G[Nmax];
int sol[Nmax],solm[Nmax][Nmax];
void KMP(int i,int j)
{
    if (marime[i]<=marime[j])
    {
        memset(stare,0,sizeof stare);
        int st=0,i1;
        for (i1=2; i1<=marime[i]; i1++)
        {
            while (st>0 && s[i][st]!=s[i][i1-1])
                st=stare[st];
            if (s[i][st]==s[i][i1-1])
                st++;
            stare[i1]=st;
        }
        st=0;
        for (i1=1; i1<=marime[j]; i1++)
        {
            while (st>0 && s[i][st]!=s[j][i1-1])
                st=stare[st];
            if (s[i][st]==s[j][i1-1])
                st++;
            if (st==marime[i])
                {
                    elim[i]=1;
                }
            }
    }
}
int KMP2(int i,int j)
{
        memset(stare,0,sizeof stare);
        int st=0,i1;
        for (i1=2; i1<=marime[i]; i1++)
        {
            while (st>0 && s[i][st]!=s[i][i1-1])
                st=stare[st];
            if (s[i][st]==s[i][i1-1])
                st++;
            stare[i1]=st;
        }
        st=0;
        for (i1=1; i1<=marime[j]; i1++)
        {
            while (st>0 && s[i][st]!=s[j][i1-1])
                st=stare[st];
            if (s[i][st]==s[j][i1-1])
                st++;
            if (i1==marime[j])
                    return st;
            }
}
void hamilton(){
     int stare,i,j;
    for (stare=1; stare<=((1<<n)-1); stare++)
    {
            for (i=0; i<n; i++)
            {
                if (((1<<i) & stare)>0 && dp[stare][i]!=-1)
                {
                    for (auto j:G[i])
                    {
                            if (((1<<j.nod) & stare)==0){
                                    if (dp[stare+(1<<j.nod)][j.nod]<dp[stare][i]+j.cost){
                                    dp[stare+(1<<j.nod)][j.nod]=dp[stare][i]+j.cost;
                                    venire[stare+(1<<j.nod)][j.nod]=i;
                                    }
                            }
                    }
                }
            }
    }
}
void creare(int i,int j)
{
    int x=KMP2(j,i);
    G[i].push_back({j,x});
    solm[i][j]=x;
}
int main()
{
    int i,j;
    fin>>n;
    s.resize(n);
    for (i=0; i<n; i++)
    {
        fin>> s[i];
        marime[i]=s[i].size();
    }

    for (i=0; i<n; i++)
    {
        for (j=0; j<n; j++)
        {
            if (i!=j)
            KMP(i,j);
        }
    }
    i=n-1;
    while (i>=0)
    {
        if (elim[i]==1)
        {
            s.erase(s.begin()+i);
            n--;
        }
            i--;
    }
    for (i=0;i<n;i++)
        marime[i]=s[i].size();
    for (i=0; i<n; i++)
    {
        for (j=i+1; j<n; j++)
        {
            creare(i,j);
            creare(j,i);
        }
    }
    for (i=1;i<=(1<<n)-1;i++)
    {
        for (j=0;j<n;j++)
        {
            dp[i][j]=-1;
        }
    }
    for (i=0;i<n;i++)
    {
        dp[1<<i][i]=0;
        venire[1<<i][i]=-1;
    }
    hamilton();
    max1=-1;
     for (i=0; i<n; i++)
    {
        if(max1<dp[(1<<n)-1][i]){
            max1=dp[(1<<n)-1][i];
            ret=i;
        }
    }
    int S=(1<<n)-1;
    int nr=1;
    sol[nr]=ret;
    while (venire[S][ret]!=-1)
    {

        int o=ret;
        ret=venire[S][ret];
        S-=(1<<o);
        nr++;
        sol[nr]=ret;
    }
    for (i=nr;i>=2;i--)
    {
        int x=solm[sol[i]][sol[i-1]];
        int y=s[sol[i]].size();
        int x1=y-x;
        for (int i1=0;i1<x1;i1++)
            fout<<s[sol[i]][i1];
    }
    fout<<s[sol[1]];
    return 0;
}