NOIP2001

<问题分析>

根据题意,可从后向前递推求出 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\n",opt[f][l1-1]);
76     while(true);
77     return 0;
78 }

 

posted @ 2013-07-05 20:42  simplesslife  阅读(176)  评论(0编辑  收藏  举报