Cod sursa(job #1173502)

Utilizator CristinaElenaFMI Ciort Elena Cristina CristinaElena Data 19 aprilie 2014 20:43:50
Problema ADN Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <fstream>
#include <vector>
#include <string>
using namespace std;

const int N = 18, SMAX = 1 << 18, LEN = 30005;

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

string s[N];
bool match[N];
int a[N][N], d[N][SMAX], n, U[LEN], t[N][SMAX];

int Dyn(int x, int stare) {
    if (d[x][stare] != -1)
        return d[x][stare];
    d[x][stare] = 0;
    for (int i = 0; i < n; ++i)
        if ((1 << i) & stare && d[x][stare] < Dyn(i, stare - (1 << i)) + a[i][x]) {
                d[x][stare] = d[i][stare - (1 << i)] + a[i][x];
                t[x][stare] = i;
            }
    return d[x][stare];
}

int kmp(string &a, string &b, bool type) {
    if (!type && a.size() > b.size())
        return 0;
    int sz_a = a.size() - 1, sz_b = b.size() - 1, k = 0;
    for (int i = 2; i <= sz_a; ++i) {
        while (k && a[k+1] != a[i])
            k = U[k];
        if (a[k+1] == a[i])
            k++;
        U[i] = k;
    }
    k = 0;
    for (int i = 1; i <= sz_b; ++i) {
        while (k && a[k+1] != b[i])
            k = U[k];
        if (a[k+1] == b[i])
            k++;
        if (k == sz_a) {
            if (!type)
                return 1;
            if (i != sz_b)
                k = U[k];
        }
    }
    return (type ? k : 0);
}

void write(int x, int stare) {
    vector <int> wr;
    while (1) {
        wr.push_back (x);
        if (!stare)
            break;
        int aux_x = x;
        x = t[x][stare];
        stare -= 1 << x;
    }
    for (int i = wr.size() - 1; i >= 0; --i)
        if (i) {
            for (int j = 1; j < s[wr[i]].size() - a[wr[i]][wr[i-1]]; j++)
                fout << s[wr[i]][j];
        }
        else
            for (int j = 1; j < s[wr[i]].size(); ++j)
                fout << s[wr[i]][j];
}

int main() {
    fin >> n;
    for (int i = 0; i < n; ++i) {
        string Input;
        fin >> Input;
        s[i] = ' ' + Input;
    }
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            if (i != j && !match[i] && !match[j])
                match[i] = kmp(s[i], s[j], 0);
    for (int i = 0; i < n; ++i)
        if (match[i]) {
            n--;
            for (int j = i; j < n; ++j) {
                match[j] = match[j+1];
                s[j] = s[j+1];
            }
            i--;
        }
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            if (i != j)
                a[i][j] = kmp(s[j], s[i], 1);
    for (int i = 0; i < n; ++i) {
        for (int j = 1; j < SMAX; ++j)
            d[i][j] = -1;
        d[i][0] = 0;
    }
    int best = 0;
    for (int i = 0; i < n; ++i)
        best = max(best, Dyn(i, (1 << n) - 1 - (1 << i)));
    for (int i = 0; i < n; ++i)
        if (best == d[i][(1 << n) - 1 - (1 << i)]) {
            write (i, (1 << n) - 1 - (1 << i));
            break;
        }
}