Cod sursa(job #1073638)

Utilizator stefanzzzStefan Popa stefanzzz Data 6 ianuarie 2014 17:30:30
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.5 kb
#include <fstream>
#include <string.h>
#include <vector>
#define MAXN 20
#define MAXC 30010
#define MAXCOD 270000
#define INF 2000000000
using namespace std;
ifstream f("adn.in");
ofstream g("adn.out");

short int nxt[MAXN][MAXCOD];
int n,a[MAXN][MAXN],kmp[MAXC],lg[MAXN],pd[MAXN][MAXCOD],x,y,cmn,cod,mn,mni,id[MAXN],idi[MAXN],cnt,aux;
bool uz[MAXN];
char s[MAXN][MAXC];
vector<int> v;

void afisare(int p,int q);

int main()
{
    int i,j,k;
    f>>n;
    f.getline(s[0]+1,MAXC,'\n');
    for(i=1;i<=n;i++){
        f.getline(s[i]+1,MAXC,'\n');
        lg[i]=strlen(s[i]+1);}
    for(j=1;j<=n;j++){
        x=0;
        for(i=2;i<=lg[j];i++){
            while(x&&s[j][i]!=s[j][x+1])
                x=kmp[x];
            if(s[j][i]==s[j][x+1])
                x++;
            kmp[i]=x;}
        for(i=1;i<=n;i++){
            if(i==j)
                continue;
            x=0;
            for(k=1;k<=lg[i];k++){
                while(x&&s[j][x+1]!=s[i][k])
                    x=kmp[x];
                if(s[j][x+1]==s[i][k])
                    x++;
                if(x==lg[j])
                    uz[j]=1;}
            a[i][j]=x;}}
    for(i=1;i<=n;i++)
        if(!uz[i]){
            id[i]=(++cnt);
            idi[cnt]=i;}
    n=cnt;
    for(i=1;i<=n;i++)
        for(j=1;j<(1<<n);j++)
            pd[i][j]=INF;
    for(cod=1;cod<(1<<n);cod++){
        v.clear();
        for(i=1;i<=n;i++)
            if(cod&(1<<(i-1)))
                v.push_back(i);
        if(v.size()==1)
            continue;
        if(v.size()==2){
            pd[v[0]][cod]=lg[idi[v[0]]]+lg[idi[v[1]]]-a[idi[v[0]]][idi[v[1]]];
            nxt[v[0]][cod]=v[1];
            pd[v[1]][cod]=lg[idi[v[0]]]+lg[idi[v[1]]]-a[idi[v[1]]][idi[v[0]]];
            nxt[v[1]][cod]=v[0];
            continue;}
        for(i=0;i<v.size();i++)
            for(j=0;j<v.size();j++){
                if(i==j)
                    continue;
                x=v[i];y=v[j];
                if(lg[idi[x]]-a[idi[x]][idi[y]]+pd[y][cod-(1<<(x-1))]<pd[x][cod]){
                    pd[x][cod]=lg[idi[x]]-a[idi[x]][idi[y]]+pd[y][cod-(1<<(x-1))];
                    nxt[x][cod]=y;}}}
    mn=INF;
    for(i=1;i<=n;i++)
        if(pd[i][(1<<n)-1]<mn){
            mn=pd[i][(1<<n)-1];
            mni=i;}
    x=mni;y=(1<<n)-1;
    while(y){
        g<<s[idi[x]]+1+cmn;
        cmn=a[idi[x]][idi[nxt[x][y]]];
        aux=x;
        x=nxt[x][y];
        y-=(1<<(aux-1));}
    f.close();
    g.close();
    return 0;
}