嗯,看到就想到爆搜,但是我没参加~悲剧~
在POJ上过了,uscOJ上却TLE,嗯,我会尝试更高端的方法。
爆搜很简单,用DFS写出全排列,再将串的位置一一对应就A了,代码如下
#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;
int t,n,ans,istrue[11],p[11],cmp[11][11];
char a[11][21],b[250];
void Init()
{
int i,j,k;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
int tag=0;
for (k=0;k<strlen(a[i]);k++)
{
for (int kk=0;kk<strlen(a[i])-k;kk++)
if (a[i][k+kk]!=a[j][kk]) break;
else if(kk==strlen(a[i])-k-1)
{
tag=1;
break;
}
if (tag==1)
{
cmp[i][j]=strlen(a[i])-k;
//printf("%d ",cmp[i][j]);
break;
}
}
}
}
void DFS(int cnt)
{
int i,j,k;
for (i=1;i<=n;i++)
{
if (istrue[i]) continue;
istrue[i]=1;
p[cnt]=i;
if (cnt==n)
{
istrue[i]=0;
int tmp=0;
for (j=1;j<n;j++)
{
tmp+=cmp[p[j]][p[j+1]];
}
if (ans<tmp) ans=tmp;
}else{
DFS(cnt+1);
istrue[i]=0;
}
}
return ;
}
int main()
{
//freopen("D_data.in","r",stdin);
//freopen("D_data1.out","w",stdout);
int i,j,k,len;
scanf("%d",&t);
while (t--)
{
len=0;
memset(istrue,0,sizeof(istrue));
memset(cmp,0,sizeof(cmp));
scanf("%d",&n);
ans=0;
for (i=1;i<=n;i++)
{
scanf("%s",a[i]);
len+=strlen(a[i]);
//printf("%s",a[i]);
}
Init();
DFS(1);
printf("%d\n",len-ans);
}
return 0;
}