Cod sursa(job #2320688)

Utilizator triscacezarTrisca Vicol Cezar triscacezar Data 15 ianuarie 2019 00:29:52
Problema ADN Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("adn.in");
ofstream g("adn.out");

int n,i,j,r,k,m,K,mask,pi[20][30010];
int dyn[1<<19][20];
vector<char> Ans;
pair<pair<int,int>,pair<int,int> > bacc[1<<19][20];
string s[20];

int main()
{
    f>>n;
    memset(dyn,127,sizeof(dyn));
    for(i=1; i<=n; i++)
    {
        f>>s[i];
        k=0;
        m=s[i].size();
        dyn[1<<(i-1)][i-1]=m;
        bacc[1<<(i-1)][i-1]={{0,0},{i,m}};
        for(j=2; j<=m; j++)
        {
            while(k&&s[i][j-1]!=s[i][k])
                k=pi[i][k];
            if(s[i][j-1]==s[i][k])
                k++;
            pi[i][j]=k;
        }
    }
    K=(1<<n);
    for(mask=1; mask<K; mask++)
        for(i=0; i<n; i++)
            if((1<<i)&mask)
                if(dyn[mask][i]<1e8)
                    for(j=0; j<n; j++)
                        if(!((1<<j)&mask))
                        {
                            k=0;
                            m=s[i+1].size();
                            bool ok=0;
                            for(r=1; r<=m; r++)
                            {
                                while(k&&s[j+1][k]!=s[i+1][r-1])
                                    k=pi[j][k];
                                if(s[j+1][k]==s[i+1][r-1]&&k<s[j+1].size())
                                    k++;
                                if(k==s[j+1].size())
                                    ok=1;
                            }
                            if(ok)
                            {
                                dyn[mask|(1<<j)][i]=min(dyn[mask|(1<<j)][i],dyn[mask][i]);
                                if(dyn[mask|(1<<j)][i]==dyn[mask][i])
                                    bacc[mask|(1<<j)][i]={{mask,i},{-1,-1}};
                            }
                            dyn[mask|(1<<j)][j]=min(dyn[mask|(1<<j)][j],dyn[mask][i]+(int)s[j+1].size()-k);
                            if(dyn[mask|(1<<j)][j]==dyn[mask][i]+(int)s[j+1].size()-k)
                                bacc[mask|(1<<j)][j]={{mask,i},{j+1,s[j+1].size()-k}};
                        }
    int ans=1e9;
    for(i=0; i<n; i++)
        ans=min(ans,dyn[K-1][i]);
    for(i=0;i<n;i++)
        if(ans==dyn[K-1][i])
            break;
    K--;
    while(K)
    {
        for(j=1;j<=bacc[K][i].second.second;j++)
            Ans.push_back(s[bacc[K][i].second.first][s[bacc[K][i].second.first].size()-j]);
        int aux=bacc[K][i].first.second;
        K=bacc[K][i].first.first;
        i=aux;
    }
    for(i=Ans.size()-1;i>=0;i--)
        g<<Ans[i];
    return 0;
}