http://10.16.23.21:8080/JudgeOnline/showproblem?problem_id=2171
(1)这个题目的代码只是抄了一遍,还没有自己独立打出来。
(2)思路其实不复杂,分为三步:
1)求两两关系len[i][j]的最优值;
2)求加入一个新元素k后的最优值dp[i|(1<<k)][k];
3)求的dp[(1<<n)-1][j]的最大值。
具体代码:


#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[1<<10+5][11]; int len[11][11]; int n; char str[11][11]; int main() { int i, j, k; int x, count; int len1, len2, Max; while(scanf("%d", &n)!=EOF, n) { memset(len, 0, sizeof(len)); for(i=0;i<n;i++) scanf("%s", str[i]); for(i=0;i<n;i++) { for(j=0;j<n;j++) if(i!=j) { Max=-1; len1=strlen(str[i]); len2=strlen(str[j]); for(k=0;k<len1;k++) { count=0; for(x=0;x<len2&&(x+k<len1);x++) if(str[i][x+k]==str[j][x]) count++; if(count>Max) Max=count; } if(Max>len[i][j]) len[i][j]=len[j][i]=Max; } } memset(dp, 0, sizeof(dp)); for(i=0;i<(1<<n);i++) for(j=0;j<n;j++) if(i&(1<<j)) for(k=0;k<n;k++) if(!(i&(1<<k))) dp[i|(1<<k)][k]=max(dp[i|1<<k][k], dp[i][j]+len[j][k]); Max=-1; for(j=0;j<n;j++) if(dp[(1<<n)-1][j]>Max) Max=dp[(1<<n)-1][j]; printf("%d\n", Max); } return 0; }