与上题类似 预处理一下各字符串之间最大的相同字符数就可以 注意dp要初始为负无穷
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stdlib.h> 5 #include<algorithm> 6 using namespace std; 7 #define N 1050 8 int dp[N][11],k[11],q[2][N],w[12][12],f[N]; 9 char s[11][11]; 10 int compare(int x,int y) 11 { 12 int i,j,maxz=0; 13 for(i = 0 ; i < k[x] ; i++) 14 for(j = 0 ; j < k[y] ; j++) 15 { 16 if(s[x][i]==s[y][j]) 17 { 18 int ii = i+1,jj = j+1,o=1; 19 while(ii<k[x]&&jj<k[y]) 20 { 21 if(s[x][ii]==s[y][jj]) 22 o++; 23 ii++;jj++; 24 } 25 maxz = max(o,maxz); 26 } 27 } 28 return maxz; 29 } 30 int main() 31 { 32 int i,j,n,e,o; 33 while(scanf("%d%*c",&n)&&n) 34 { 35 int kk=0; 36 memset(w,0,sizeof(w)); 37 memset(dp,128,sizeof(dp)); 38 memset(f,0,sizeof(f)); 39 for(i = 0; i < n ; i++) 40 { 41 scanf("%s",s[i]); 42 k[i] = strlen(s[i]); 43 } 44 for(i =0 ; i < n ;i++) 45 { 46 q[0][i] = 1<<i; 47 dp[1<<i][i] = 0; 48 } 49 kk = n; 50 for(i =0; i < n ; i++) 51 for(j = i+1; j < n ; j++) 52 { 53 w[i][j] = compare(i,j); 54 w[j][i] = w[i][j]; 55 } 56 for(i = 1 ; i < n ; i++) 57 { 58 int tt=0; 59 for(j = 0 ; j < kk ; j++) 60 { 61 for(e = 0 ; e < n ; e++) 62 { 63 for(o = 0 ; o < n ; o++) 64 { 65 if(((~q[(i-1)%2][j])&(1<<o))==0) 66 continue; 67 int oo = q[(i-1)%2][j]+(1<<o); 68 if(o==e) 69 continue; 70 dp[oo][o] = max(dp[oo][o],dp[q[(i-1)%2][j]][e]+w[e][o]); 71 if(!f[oo]) 72 { 73 q[i%2][tt++] = oo; 74 f[oo] = 1; 75 } 76 } 77 } 78 } 79 kk = tt; 80 } 81 int ans = 0; 82 for(i = 0 ; i < n ;i++) 83 ans = max(ans,dp[(1<<n)-1][i]); 84 printf("%d ",ans); 85 } 86 return 0; 87 }