Cod sursa(job #945427)

Utilizator sergiu97Ilea Sergiu sergiu97 Data 1 mai 2013 21:32:33
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <fstream>
#include <string>

using namespace std;

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

const int nmax=18, lmax= 30000;
const int n2max= 1<<nmax;

string s[nmax];

int pf[lmax];
int kmp(int x, int y){
    int p= 0;
    for (int i= 1; i<(int)s[x].size(); ++i){
        while (p>0&& s[x][p]!=s[x][i]){
            p= pf[p-1];
        }
        if (s[x][p]==s[x][i]){
            ++p;
        }
        pf[i]= p;
    }

    p= 0;
    for (int i= 0; i<(int)s[y].size(); ++i){
        while (p>0&& s[x][p]!=s[y][i]){
            p= pf[p-1];
        }
        if (s[x][p]==s[y][i]){
            ++p;
        }
        if (p==(int)s[x].size()){
            return p;
        }
    }
    return p;
}
int cst[nmax][nmax];
int mv[nmax];

int d[n2max][nmax];

int w[nmax+1];
void write(int key, int ind, int n){
    if ((key&(key-1))==0){
        ++w[0]; w[w[0]]= ind;
        return;
    }else{
        int i;
        for (i= 0; i<n; ++i){
            if (i!=ind&& (key&(1<<i))&& d[key][ind]==d[key-(1<<ind)][i]+cst[i][ind]){
                break;
            }
        }
        write(key-(1<<ind), i, n);
        ++w[0]; w[w[0]]= ind;
    }
}

int main(){
    int n;
    fin>>n;
    for (int i= 0; i<n; ++i){
        fin>>s[i];
    }

    for (int i= 0; i<n; ++i){
        for (int j= 0; j<n; ++j){
            if (i!=j){
                cst[i][j]= kmp(j, i);
            }
        }
    }

    int n_aux= 0;
    for (int i= 0; i<n; ++i){
        int j;
        for (j= 0; j<n; ++j){
            if (cst[j][i]==(int)s[i].size()&& s[i].size()!=s[j].size()){
                break;
            }
        }
        if (j==n){
            mv[n_aux]= i;
            ++n_aux;
        }
    }
    n= n_aux;
    for (int i= 0; i<n; ++i){
        s[i]= s[mv[i]];
        for (int j= 0; j<n; ++j){
            cst[i][j]= cst[mv[i]][mv[j]];
        }
    }

    int n2= 1<<n;
    for (int i= 1; i<n2; ++i){
        for (int j= 0; j<n; ++j){
            if (i&(1<<j)){
                for (int k= 0; k<n; ++k){
                    if (j!=k&& (i&(1<<k))&& d[i][j]<d[i-(1<<j)][k]+cst[k][j]){
                        d[i][j]= d[i-(1<<j)][k]+cst[k][j];
                    }
                }
            }
        }
    }

    int sol= 0, ind= -1;
    for (int i= 0; i<n; ++i){
        if (sol<=d[n2-1][i]){
            sol= d[n2-1][i];
            ind= i;
        }
    }
    write(n2-1, ind, n);
    fout<<s[w[1]];
    for (int i= 2; i<=w[0]; ++i){
        for (int j= cst[w[i-1]][w[i]]; j<(int)s[w[i]].size(); ++j){
            fout<<s[w[i]][j];
        }
    }

}