//题目链接:
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; }