Cod sursa(job #1148245)

Utilizator tudorv96Tudor Varan tudorv96 Data 20 martie 2014 17:07:30
Problema ADN Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
#include <fstream>
//#include <iostream>
#include <vector>
#include <string>
using namespace std;

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

const int N = 18, SZ = 30005;

#define nod first
#define stare second

string s[N];
int n, d[N][1 << N], a[N][N], best;
pair <int, int> t[N][1 << N];
bool match[N];

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

int kmp(string &a, string &b, bool det) {
    if (det && a.size() > b.size())
        return 0;
    vector <int> U(SZ, 0);
    int k = 0, sz_a = a.size() - 1, sz_b = b.size() - 1;
    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 (det)
                return 1;
            if (i != sz_b)
                k = U[k];
        }
    }
    if (det)
        return 0;
    return k;
}

void write(int node, int st) {
    if (st)
        write (t[node][st].nod, t[node][st].stare);
    else
        return;
    if (!t[node][st].stare) {
        for (int i = 1; i < s[node].size(); ++i)
            fout << s[node][i];
        return;
    }
    for (int i = 1; i < s[node].size() - a[t[node][st].nod][node]; ++i)
        fout << s[node][i];
    //fout << "\n";
}

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 && kmp(s[i], s[j], 1))
                match[i] = 1;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            if (i != j && !match[i] && !match[j])
                a[i][j] = kmp(s[i], s[j], 0);
    /*for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j)
            cout << a[i][j] << " ";
        cout << "\n";
    }*/
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < (1 << n); ++j)
            d[i][j] = -1;
    for (int i = 0; i < n; ++i)
        if (!match[i])
            best = max(best, Dyn(i, (1 << n) - 1 - (1 << i)));
   for (int i = 0; i < n; ++i)
        if (d[i][(1 << n) - 1 - (1 << i)] == best)
            write(i, (1 << n) - 1 - (1 << i));
    //fout << "\n" << best;
}