Cod sursa(job #3333739)

Utilizator GabiRB1Rafael GabiRB1 Data 14 ianuarie 2026 23:22:46
Problema ADN Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.46 kb
#include <bits/stdc++.h>

using namespace std;
string s[20];
int c[20][20], ii, jj;
bool included(string &s1, string &s2)
{
    return s2.find(s1) != string::npos;
}
bool deleteString(int i, int j)
{
    if(s[i].length() <= s[j].length())
    {
        if(included(s[i], s[j]))
            return 1;
    }
    //else if(included(s[j], s[i]))
    //  return 1;
    return 0;
}

string s3 = "";
int calc(string &s11, string &s2, string &s3)
{
    if(s3 == "")
    {
        unordered_set<unsigned int> s;
        unsigned int b = 137, nr = 0, p = 1;
        unordered_set<unsigned long long> s1;
        unsigned long long b1 = 139, nr1 = 0, p1 = 1;
        for(int i = s11.length() - 1; i >= 0; i --)
            nr = nr + (s11[i] - 'A' + 1) * p, p *= b, s.insert(nr),
                                                    nr1 = nr1 + (s11[i] - 'A' + 1) * p1, p1 *= b1,  s1.insert(nr1);

        nr = 0;
        nr1 = 0;
        int maxx = 0;
        for(int i = 0; i < s2.length(); i ++)
        {
            nr = nr * b + s2[i] - 'A' + 1;
            nr1 = nr1 * b1 + s2[i] - 'A' + 1;
            if(s.find(nr) != s.end() && s1.find(nr1) != s1.end())
                maxx = i + 1;
        }
        return s2.length() - maxx;
    }


    int pluss = c[ii][jj];
    int maxx = s2.length() - pluss;
    for(int i = maxx; i < s2.length(); i ++)
        s3 += s2[i];
    return 0;

}


int dp[18][(1 << 18) + 5], n;
short t[18][(1 << 18) + 6];
int main()
{
    ifstream f("adn.in");
    ofstream g("adn.out");
    f >> n;
    for(int i = 0; i < n; i ++)
        f >> s[i];
    for(int i = 0; i < n; i ++)
        for(int j = 0; j < n; j ++)
            if(i != j)
                if(deleteString(i, j))
                {
                    for(int p = i; p < n - 1; p ++)
                        s[p] = s[p + 1];
                    n --;
                    i --;
                    break;
                }

    for(int i = 0; i < n; i ++)
        for(int j = 0; j < n; j ++)
            if(i != j)
            c[i][j] = calc(s[i], s[j], s3);
        else c[i][j] = 0;


    for(int j = 0; j < n; j ++)
        for(int p = 0; p < (1 << n); p ++)
            dp[j][p] = 1e9;

    for(int i = 0; i < n; i ++)
        dp[i][(1 << i)] = s[i].length();


    for(int mask = 1; mask < (1 << n); mask ++)
    {
        for(int i = 0; i < n; i ++)
            if(mask & (1 << i))
            {
                int prev = mask ^ (1 << i);
                for(int j = 0; j < n; j ++)
                    if(prev & (1 << j))
                    {
                        if(dp[j][prev] + c[j][i] <= dp[i][mask])
                            dp[i][mask] = dp[j][prev] + c[j][i],
                                          t[i][mask] = j;
                    }
            }
    }

    int minn = 1e9, pozi, pozj, mask = (1 << n) - 1;
    for(int j = 0; j < n; j ++)
    {
        if(dp[j][mask] < minn)
            minn = min(minn, dp[j][mask]), pozj = j;
    }

    vector<int> rez;
//rez.push_back(pozj);
    while(mask != 0)
    {
        rez.push_back(pozj);
        int aux = t[pozj][mask];
        mask = mask ^ (1 << pozj);
        pozj = aux;
    }
    string s_Rez = "";
    reverse(rez.begin(), rez.end());
    s_Rez = s[rez[0]];

    for(int i = 1; i < n; i ++)
    {
        ii = rez[i - 1], jj = rez[i];
        calc(s[rez[i - 1]], s[rez[i]], s_Rez);
    }
    g << s_Rez;
//g << minn;


    return 0;
}