Cod sursa(job #848373)

Utilizator SebiSebiPirtoaca George Sebastian SebiSebi Data 5 ianuarie 2013 13:31:23
Problema ADN Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.43 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],r[NMAX],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;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			if(r[j]==0 && i!=j) {
				if(KMP(c[j],c[i])) {
					r[i]=1;
					break;
				}
			}
}

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++;
		if(k==m)
			k=l[m];
	}
	return k;
}

inline void builtgraph(int n)
{
	int i,j;
	muchie x;
	for(i=1;i<=n;i++) {
		if(r[i]==1)
			continue;
		prefix(c[i],strlen(c[i]+1));
		for(j=1;j<=n;j++)
			if(i!=j && r[j]==0) {
				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) && r[it->y]==0) {
			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) {
		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);
	builtgraph(n);
	memset(d,-1,sizeof(d));
	for(i=1;i<=n;i++)
		if(r[i]==0) 
			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(r[i]==0 && d[i][s]>cost) {
			cost=d[i][s];
			x=i;
		}
	afisare(x,s);
	return 0;
}