Cod sursa(job #2703421)

Utilizator stefantagaTaga Stefan stefantaga Data 8 februarie 2021 15:53:06
Problema ADN Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("adn.in");
ofstream g("adn.out");
vector <int> v;
int n,i,j,urm[30005],k,cost[20][20],fr[20],ok,maxim,ok1[20],dp[20][(1<<18)+10],lim,mask,inainte[20][(1<<18)+10],minim,sol;
string s[20],s2;
void reconst(int mask,int poz)
{
    if (__builtin_popcount(mask)==1)
    {
        if (s[v[poz]].size()>1)
        {
            g<<s[v[poz]];
        }
        return ;
    }
    int antlist=inainte[poz][mask];
    reconst(mask^(1<<poz),antlist);
    for (int i=cost[v[antlist]][v[poz]];i<s[v[poz]].size();i++)
    {
        g<<s[v[poz]][i];
    }
}
int main()
{
    f>>n;
    for (i=1;i<=n;i++)
    {
        f>>s[i];
    }
    for (i=1;i<=n;i++)
    {
        for (j=1;j<=n;j++)
        {
            if (i!=j)
            {
                s2=s[j]+'#'+s[i];
                urm[0]=0;
                k=0;
                for (int t=1;t<s2.size();t++)
                {
                    while (k>0&&s2[t]!=s2[k])
                    {
                        k=urm[k-1];
                    }
                    if (s2[t]==s2[k])
                    {
                        k++;
                    }
                    urm[t]=k;
                    if (urm[t]==s[j].size())
                    {
                        ok1[j]=1;
                    }
                }
                cost[i][j]=urm[s2.size()-1];
            }
        }
    }
    for (i=1;i<=n;i++)
    {
        if (ok1[i]==0)
        {
            v.push_back(i);
        }
    }
    memset(dp,0x3f,sizeof(dp));
    lim=(1<<v.size());
    for (mask=1;mask<lim;mask++)
    {
        for (i=0;i<v.size();i++)
        {
             if (!(mask & (1<<i)))
             {
                 continue;
             }
             if (__builtin_popcount(mask)==1)
             {
                 dp[i][mask]=s[v[i]].size();
             }
                for (k=0;k<v.size();k++)
                {
                    if (mask&(1<<k))
                    {
                        continue;
                    }
                    if (k==3&&(mask^(1<<k))==lim-1)
                    {
                        k++;
                        k--;
                    }
                    if (dp[k][mask^(1<<k)]>dp[i][mask]+s[v[k]].size()-cost[v[i]][v[k]])
                    {
                        dp[k][mask^(1<<k)]=dp[i][mask]+s[v[k]].size()-cost[v[i]][v[k]];
                        inainte[k][mask^(1<<k)]=i;
                    }
                }
        }
    }
    minim=1e9;
    for (i=0;i<v.size();i++)
    {
        if (dp[i][lim-1]<minim)
        {
            minim=dp[i][lim-1];
            sol=i;
        }
    }
    reconst(lim-1,sol);
    return 0;
}