Cod sursa(job #3359972)

Utilizator Zeno1789Zeno Ciuca Zeno1789 Data 7 iulie 2026 11:05:45
Problema ADN Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

ifstream cin("adn.in");
ofstream cout("adn.out");

int overlap[20][20];
int dp[1<<18][18];
int parent[1<<18][18];

int main() {
    int initial_n;
    cin>>initial_n;
    vector<string> temp(initial_n);
    for (int i=0; i<initial_n; ++i) {
        cin>>temp[i];
    }
    sort(temp.begin(), temp.end(), [](const string& a, const string& b) {
        return a.length() > b.length();
    });
    vector<string> words;
    for (int i=0; i<initial_n; ++i) {
        bool ok=true;
        for (string& w : words) {
            if (w.find(temp[i]) != string::npos) {
                ok=false;
                break;
            }
        }
        if (ok) {
            words.push_back(temp[i]);
        }
    }
    int n=words.size();
    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j) {
            if (i!=j) {
                int max_ov=0;
                int max_possible=min(words[i].length(), words[j].length());
                for (int len=1; len<=max_possible; ++len) {
                    if (words[i].substr(words[i].length()-len) == words[j].substr(0, len)) {
                        max_ov=len;
                    }
                }
                overlap[i][j]=max_ov;
            }
        }
    }
    int limit=(1<<n);
    for (int mask=0; mask<limit; ++mask) {
        for (int i=0; i<n; ++i) {
            dp[mask][i]=1e9;
        }
    }
    for (int i=0; i<n; ++i) {
        dp[1<<i][i]=words[i].length();
    }
    for (int mask=1; mask<limit; ++mask) {
        for (int i=0; i<n; ++i) {
            if (dp[mask][i]==1e9) {
                continue;
            }
            for (int j=0; j<n; ++j) {
                if (!(mask & (1<<j))) {
                    int nxt=mask | (1<<j);
                    int cost=dp[mask][i]+words[j].length()-overlap[i][j];
                    if (cost < dp[nxt][j]) {
                        dp[nxt][j]=cost;
                        parent[nxt][j]=i;
                    }
                }
            }
        }
    }
    int mask=limit-1, last=0, min_len=dp[mask][0];
    for (int i=1; i<n; ++i) {
        if (dp[mask][i] < min_len) {
            min_len=dp[mask][i];
            last=i;
        }
    }
    vector<int> order;
    while (mask > 0) {
        order.push_back(last);
        int p=parent[mask][last];
        mask ^=(1<<last);
        last=p;
    }
    reverse(order.begin(), order.end());
    string ans=words[order[0]];
    for (int i=1; i<order.size(); ++i) {
        ans+=words[order[i]].substr(overlap[order[i-1]][order[i]]);
    }
    cout<<ans<<"\n";
}