Cod sursa(job #498589)

Utilizator mare95Mare Adrian Sorin mare95 Data 5 noiembrie 2010 16:28:13
Problema ADN Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <cstdio>
#include <vector>

using namespace std;

FILE *in,*out;

char s[19][30050];
int d[20][20];
int a[(1<<18)+5][20];
int pi_aux[30050];
int pi[19][30050];
int pred[(1<<18)+5][20];
const int inf=1<<29;
int size[30];
int b[30],inutil[30];
int gen_pi(int x)
{
	int i,y;
	pi[x][1]=0;
	for (i=2;s[x][i];i++)
	{
		y=pi[x][i-1];
		while (y&&s[x][y+1]!=s[x][i])
			y=pi[x][y];
		if (s[x][y+1]==s[x][i])
			y++;
		pi[x][i]=y;
	}
	return i-1;
}
int search(int x,int y)
{
	int i,z;
	pi_aux[1]=0;
	for (i=2;s[y][i];i++)
	{
		z=pi_aux[i-1];
		while (z&& s[x][z+1]!=s[y][i])
			z=pi[x][z];
		if (s[x][z+1]==s[y][i])
				z++;
		pi_aux[i]=z;
		if (pi_aux[i]==size[x])
			return size[x];
	}
	return pi_aux[i-1];
}
void afis(int i,int j)
{
	if (!i)
		return ;
	afis(i-(1<<(j-1)),pred[i][j]);
	int k;
	for (k=-d[b[pred[i][j]]][b[j]]+1;k<=size[b[j]];k++)
		fprintf(out,"%c",s[b[j]][k]);
}
int main()
{
	int i,n,len=0,j,k,q,q2,minv,x,nr=0;
	in=fopen("adn.in","r");
	out=fopen("adn.out","w");
	fscanf(in,"%d",&n);
	for (i=1;i<=n;i++)
	{
		fscanf(in,"%s",s[i]+1);

		size[i]=gen_pi(i);
		len+=size[i];
	}
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=n;j++)
			if (j!=i)
			{
				d[i][j]=-search(j,i);
				if (d[i][j]==-size[j])
					inutil[j]=1;
			}
	}
	nr=0;
	for (i=1;i<=n;i++)
		if (!inutil[i])
		{
			nr++;
			b[nr]=i;
		}
	q=(1<<nr);
	for (i=0;i<q;i++)
		for (j=1,q2=1;j<=nr;j++,q2=1<<(j-1))
			if (i&q2)
			{
				minv=0;
				for (k=1;k<=nr;k++)
					if (k!=j && (i & (1<<(k-1))))
					{
						if (a[i-q2][k]+d[b[k]][b[j]]<=minv)
						{
							minv=a[i-q2][k]+d[b[k]][b[j]];
							pred[i][j]=k;
						}
					}
				a[i][j]=minv;
			}
	minv=1;
	for (i=1;i<=nr;i++)
	{
		if( a[q-1][i]<minv)
		{
			x=i;
			minv=a[q-1][i];
		}
	}
	fprintf(stderr,"%d %d %d\n",minv,len,nr);
	afis(q-1,x);
	fclose(in);
	fclose(out);
	return 0;
}