<问题分析>
根据题意,可从后向前递推求出 sum[i][j]即从串i到j中有单词的最大个数
状态转移方程opt[i][j]=max{opt[i][t]+sum[t+1][j]} i,j表示到下标j形成了i个划分
1 #include <stdio.h> 2 #include <string.h> 3 4 5 #define N 200+10 6 7 8 char s[N],s1[21],w[7][21]; 9 10 11 int cmp(char *s1,char *s2,int i,int j) 12 { 13 int l1=strlen(s1); 14 for(int k=0;k<l1;k++) 15 { 16 if(k>j-i||s1[k]!=s2[i+k]) 17 return 0; 18 } 19 return 1; 20 } 21 22 int find(int i,int j,int l) 23 { 24 for(int k=1;k<=l;k++) 25 { 26 if(cmp(w[k],s,i,j)) 27 return 1; 28 } 29 return 0; 30 } 31 32 int main() 33 { 34 int sum[N][N],opt[N][N],i,j,k,l1,l,f,tag; 35 scanf("%d %d",&l,&f); 36 s[0]=0; 37 for(i=1;i<=l;i++) 38 { 39 scanf("%s",s1); 40 strcat(s,s1); 41 } 42 scanf("%d",&l); 43 for(i=1;i<=l;i++) 44 { 45 scanf("%s",w[i]); 46 } 47 l1=strlen(s); 48 for(i=1;i<=l1;i++) 49 sum[i][i-1]=0; 50 for(i=l1-1;i>=0;i--) 51 { 52 for(j=i;j<l1;j++) 53 { 54 if(find(i,j,l)) 55 sum[i][j]=sum[i+1][j]+1; 56 else 57 sum[i][j]=sum[i+1][j]; 58 } 59 } 60 for(i=0;i<l1;i++) 61 opt[1][i]=sum[0][i]; 62 for(i=2;i<=f;i++) 63 { 64 for(j=i;j<l1;j++) 65 { 66 tag=0; 67 for(k=i;k<j;k++) 68 { 69 if(tag<opt[i-1][k]+sum[k+1][j]) 70 tag=opt[i-1][k]+sum[k+1][j]; 71 } 72 opt[i][j]=tag; 73 } 74 } 75 printf("%d ",opt[f][l1-1]); 76 while(true); 77 return 0; 78 }