hnu-City Merger

//题目链接:

http://acm.hnu.cn/online/?action=problem&type=show&id=12525&courseid=237

//这题只要转化成一个经典的类tsp问题就好了,只不过出发了不需要回到原点,直接用状态压缩来解;

 

//代码如下:

#include<stdio.h>
#include<string.h>
int map[20][20],n,vis[20],len[20];
char str[20][30],s[20][30];
int find(char *s1,char *s2)
{
	int i,j,sum,l;
	sum=strlen(s1);
	while(sum>=0)
	{
		l=strlen(s1);
		i=l-sum;
		for(j=0;i<l&&i>=0&&s2[j]&&s1[i]==s2[j];i++,j++);
		if(i==l)break;
		sum--;
	}
	return sum;
}
int dp[100000][15];
int Max(int a,int b){return a>b?a:b;}
int tsp(int n)
{
	int i,k,j;
	for(k=0;k<=n;k++)
		for(i=0;i<=((1<<(n+1))-1);i++)
			dp[i][k]=0;
	dp[1][0]=0;
	for(i=1;i<=(1<<(n+1))-1;i+=2)
		for(j=0;j<=n;j++)
			if(i&(1<<j))
				for(k=1;k<=n;k++)
					if(!(i&(1<<k)))
						dp[i|1<<k][k]=Max(dp[i|1<<k][k],dp[i][j]+map[j][k]);
	k=dp[(1<<(n+1))-1][1];
	for(i=2;i<=n;i++)
		k=Max(k,dp[(1<<(n+1))-1][i]);
	return k;
}
int flag[20];
int main()
{
	int i,j,sum;
	while(scanf("%d",&n),n)
	{
		sum=0;
		memset(map,0,sizeof(map));
		for(i=1;i<=n;i++)
		{
			scanf("%s",str[i]);
			len[i]=strlen(str[i]);
		}
		memset(flag,0,sizeof(flag));
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				if(i!=j&&len[i]<=len[j]&&strstr(str[j],str[i])!=NULL)
				{
					flag[i]=1;
					break;
				}
			}
		}
		for(i=1,j=0;i<=n;i++)
		{
			if(!flag[i])
			{
				strcpy(s[++j],str[i]);
				len[j]=len[i];
				sum+=len[i];
			}
		}
		n=j;
		for(i=0;i<=n;i++)
			for(j=0;j<=n;j++)
				map[i][j]=0;
		for(i=1;i<=n;i++)
		{
			for(j=i+1;j<=n;j++)
			{
				map[i][j]=find(s[i],s[j]);
				map[j][i]=find(s[j],s[i]);
			}
		}
		printf("%d\n",sum-tsp(n));
	}
	return 0;
}


 

你可能感兴趣的:(hnu-City Merger)