Cod sursa(job #3333728)

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

using namespace std;
string s[20];
int c[20][20];
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)
{
    unordered_set<int> s;
    long long b = 137, mod = 1e9 + 7, nr = 0, p = 1;
    unordered_set<int> s1;
    long long b1 = 139, mod1= 1e9 + 9, nr1 = 0, p1 = 1;
    for(int i = s11.length() - 1; i >= 0; i --)
        nr = nr + (s11[i] - 'A' + 1) * p, nr %= mod, p *= b, p %= mod, s.insert(nr),
        nr1 = nr1 + (s11[i] - 'A' + 1) * p1, nr1 %= mod1, p1 *= b1, p1 %= mod1, s1.insert(nr1);

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

    if(s3 != "")
    {
        for(int i = maxx; i < s2.length(); i ++)
            s3 += s2[i];
    }
    return s2.length() - maxx;

}


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 ++)
            c[i][j] = calc(s[i], s[j], s3);


    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] = min(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 ++)
    {
        calc(s[rez[i - 1]], s[rez[i]], s_Rez);
    }
    g << s_Rez;
//g << minn;


    return 0;
}