Cod sursa(job #3239220)

Utilizator Allie28Radu Alesia Allie28 Data 3 august 2024 02:50:28
Problema ADN Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <unordered_map>
#include <climits>

using namespace std;

ifstream fin("adn.in");
ofstream fout("adn.out");

const int LMAX = 30005;
const int INF = 0x3f3f3f3f;

int pi[20][LMAX], dp[(1<<18)], cost[20][20], from[(1<<18)];
char a[20][LMAX];
bool notok[20];

void Pi(char* s, int pos) {
    int k = 0, n = strlen(s + 1);
    for (int i = 2; i <= n; i++) {
        while (k && s[k + 1] != s[i]) {
            k = pi[pos][k];
        }
        if (s[k + 1] == s[i]) k++;
        pi[pos][i] = k;
    }
}

int calc(int x, int y) {
    if (x == y) {
        return -INF;
    }
    int k = 0, m = strlen(a[y] + 1), n = strlen(a[x] + 1);
    for (int i = 1; i <= m; i++) {
        while (k && a[x][k + 1] != a[y][i]) {
            k = pi[x][k];
        }
        if (a[x][k + 1] == a[y][i]) {
            k++;
        }
        if (k == n) { //s a regasit total cuvantul x
            notok[x] = 1;
        }
    }
    return k;
}

void reconst(int mask) {
    if (mask) {
        reconst((mask^(1<<from[mask])));
        if (mask&(mask - 1)) {
//            fout<<2<<" "<<cost[from[(mask^(1<<from[mask]))]][from[mask]]<<" "<<from[(mask^(1<<from[mask]))]<<" "<<from[mask]<<" ";
            fout<<(a[from[mask]] + 1 + cost[from[(mask^(1<<from[mask]))]][from[mask]]);
        }
        else {
//            fout<<1<<" ";
            fout<<a[from[mask]] + 1;
        }
//        fout<<endl;
    }
}


int main() {
    int n, i, j;
    fin>>n;
    fin.get();
    for (i = 0; i < n; i++) {
        fin.get(a[i] + 1, LMAX);
        fin.get();
        Pi(a[i], i);
    }
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            //calculez costul
            cost[i][j] = calc(j, i); //pun j la capatul lui i
        }
    }
    for (i = 0; i < n; i++) {
        dp[(1<<i)] = strlen(a[i] + 1);
        from[(1<<i)] = i;
    }
    int mask, tot;
    tot = 0;
    for (i = 0; i < n; i++) {
        if (!notok[i]) {
            tot += (1<<i);
        }
    }
    //vreau ca la final in masca sa ma costul maxim
    for (mask = 1; mask <= tot; mask++) {

        if (dp[mask] == 0) dp[mask] = -INF;

        for (i = 0; (1<<i) <= mask; i++) {
            if ((mask&(1<<i)) && !notok[i]) {
                for (j = 0; (1<<j) <= mask; j++) {
                    if (i != j && (mask&(1<<j)) && !notok[j]) {
                        if (dp[(mask^(1<<i))] + strlen(a[i] + 1) - cost[j][i] < dp[mask]) {
                            dp[mask] = dp[(mask^(1<<i))] + strlen(a[i] + 1) - cost[j][i];
                            from[mask] = i;
                        }
                    }
                }
            }
        }
    }
    mask--;
    reconst(mask);




    fin.close();
    fout.close();
    return 0;
}