Cod sursa(job #848639)

Utilizator SebiSebiPirtoaca George Sebastian SebiSebi Data 5 ianuarie 2013 17:40:59
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.11 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<string.h>
using namespace std;
 
#define NMAX 19
#define LMAX 30005
 
struct muchie {
    int cost,y;
};
 
vector <muchie> v[NMAX];
int l[LMAX],d[NMAX][(1<<NMAX)+1],nod[NMAX][(1<<NMAX)+1],a[NMAX][NMAX];
char c[NMAX][LMAX];
 
inline void prefix(char s[], int n)
{
    int i,k;
    l[1]=0;
    for(i=2;i<=n;i++) {
        k=l[i-1];
        while(k && s[k+1]!=s[i])
            k--;
        if(s[k+1]==s[i])
            k++;
        l[i]=k;
    }
}
 
inline int KMP(char s[], char  p[])
{
    int i,k,n,m;
    n=strlen(s+1);
    m=strlen(p+1);
    prefix(p,m);
    k=0;
    for(i=1;i<=n;i++) {
        while(k && p[k+1]!=s[i])
            k=l[k];
        if(p[k+1]==s[i])
            k++;
        if(k==m) 
            return 1;
    }
    return 0;
}
 
inline void remove(int &n)
{
    int i,j,aux;
    for(i=1;i<=n;i++) {
        aux=n;
        for(j=1;j<=n;j++)
            if(i!=j) {
                if(KMP(c[j],c[i])) {
                    strcpy(c[i],c[n]);
                    n--;
                    break;
                }
            }
        if(aux!=n)
            i--;
    }
}
 
inline int KMP2(char s[], char p[])
{
    int i,k,n,m;
    n=strlen(s+1);
    m=strlen(p+1);
    k=0;
    for(i=1;i<=n;i++) {
        while(k && s[i]!=p[k+1])
            k=l[k];
        if(s[i]==p[k+1])
            k++;
    }
    return k;
}
 
inline void builtgraph(int n)
{
    int i,j;
    muchie x;
    for(i=1;i<=n;i++) {
        prefix(c[i],strlen(c[i]+1));
        for(j=1;j<=n;j++)
            if(i!=j) {
                x.y=j;
                x.cost=KMP2(c[j],c[i]);
                v[i].push_back(x);
                a[i][j]=x.cost;
            }
    }
}
 
inline int BIT(int nr, int i)
{
    return (nr & (1<<i))!=0;
}
 
inline int dp(int i, int s)
{
    if((1<<i)+1==s) {
        d[i][s]=0;
        return 0;
    }
    if(d[i][s]!=-1)
        return d[i][s];
    int cost;
    for(vector <muchie> :: iterator it=v[i].begin();it!=v[i].end();it++) 
        if(BIT(s,it->y)) {
            cost=dp(it->y,s-(1<<i))+it->cost;
            if(d[i][s]<cost) {
                d[i][s]=cost;
                nod[i][s]=it->y;
            }
        }
    return d[i][s];
}
 
ofstream g("adn.out");
 
inline void afisare(int i, int s)
{
    if((1<<i)+1==s || i<=0) {
        g<<c[i]+1;
        return;
    }
    int x;
    x=nod[i][s];
    afisare(x,s-(1<<i));
    g<<c[i]+a[i][x]+1;
}
     
int main ()
{
    int i,n,cost,x,s;
    ifstream f("adn.in");
    f>>n;
    for(i=1;i<=n;i++) {
        f>>(c[i]+1);
        c[i][0]=' ';
    }
    f.close();
    remove(n);
    if(n==1) {
        g<<c[1]+1;
        g<<'\n';
        g.close();
        return 0;
    }
    builtgraph(n);
    memset(d,-1,sizeof(d));
    for(i=1;i<=n;i++)
		d[i][(1<<(n+1))-1]=dp(i,(1<<(n+1))-1);
    cost=-1;
    s=(1<<(n+1))-1;
    for(i=1;i<=n;i++)
        if(d[i][s]>cost) {
            cost=d[i][s];
            x=i;
        }
    afisare(x,s);
    g<<'\n';
    g.close();
    return 0;
}