d
#include<iostream> #include<string.h> #include<stdio.h> int mark[1002],link[1002],n; char s[202][1020]; int g[202][202],s[202],t[202],lx[202],ly[202],link[202]; char temp[1002]; int min(int x,int y) { return x>y?y:x; } void rev(int x,int len) { int i,j; for(i=0,j=len-1;i<len;i++,j--) temp[j]=s[x][i]; } void build() { int i,j,len,k,count; for(i=0;i<n;i++) for(j=0;j<n;j++) { int len=strlen(s[i]); rev(i,len); count=0; for(k=0;temp[k]==s[j][k]&&k<len;k++) count++; g[i][j]=count; } } int dfs(int x) { s[x]=1; for(i=0;i<n;i++) { if(lx[i]+ly[i]>=g[i][j]&&!t[i]) { t[i]=1; if(link[i]==-1||dfs(link[i]) { link[i]=x; return 1; } } } return 0; } void update() { int a=1<<30; for(i=0;i<n;i++) if(s[i]) for(j=0;j<n;j++) if(!t[i]) a=min(a,lx[i]+ly[i]-g[i][j]); for(i=0;i<n;i++) { if(s[i]) lx[i]-=a; if(t[i]) ly[i]+=a; } } void KM(); { for(i=0;i<n;i++) { lx[i]=ly[i]=0; for(j=0;j<n;j++) lx[i]=min(lx,g[i][j]); } memset(link,-1,sizeof(link)); for(i=0;i<n;i++) { while(1) { memset(s,0,sizeof(s)); memset(t,0,sizeof(t)); if(dfs(i)) break; else update(); } } } int main() { int i,j; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) scanf("%s",s[i]); build(); /*for(i=0;i<n;i++) { for(j=0;j<n;j++) printf("%d",g[i][j]); printf("\n"); }*/ KM(); int ans=0; for(i=0;i<n;i+) ans+=(g[link[i][i]); printf("%d\n",ans); } return 0; }