USACO 2.3.1 The Longest Prefix

昨天看的题目,说是dp,我就想公式推导了很久没出来,睡觉前想,竟然一直想到天亮,因为鼻塞,痛苦了一晚上,果断旷课睡觉。终于,想到了一条类似枚举的算法,就是用dp[i]记录前i个字符是否已经可以匹配了,如果匹配的话就dp[i]=1 else 0.

然后枚举每个单词进去,看加了这个单词后是否能够匹配,匹配就dp[i+单词长度]=1,最后从最后扫回去看dp最后的1是哪个位置就是答案了。时间竟然也不是很高,骄傲啊!可惜一开始输入那里出现了问题,导致答案都是0,奇怪死了,后来把它改成判断A到Z再存入就ac了,不懂。。。

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<stdlib.h>
 5 #define max(a,b) a>b?a:b
 6 #define min(a,b) a>b?b:a
 7 #define INF     0x3f3f3f3f
 8 #define Maxin 10000
 9 int fang[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
10 int cmp(const void*x,const void*y);
11 char s[200001];
12 char sj[201][12];
13 int dp[200001];
14 int sjn=0,sn=0;
15 bool cmp(int x,int y)//判断是否匹配
16 {
17     int i,j=0,l=strlen(sj[x]);
18     for(i=y;;i++)
19     {
20         if(s[i]==sj[x][j])
21             j++;
22         else
23             return false;
24         if(j==l)
25             return true;
26     }
27 }
28 int main()
29 {
30     int x,y,l=0;
31     char sc;
32     memset(dp,0,sizeof(dp));
33     while(1)
34     {
35         scanf("%s",sj[sjn]);
36         if(sj[sjn][0]!='.')
37             sjn++;
38         else
39             break;
40     }
41     while(scanf("%c",&sc)!=EOF)
42     {
43         if(sc>='A'&&sc<='Z')
44             s[l++]=sc;
45     }
46     dp[0]=1;
47     for(y=0;y<l;y++)
48        for(x=0;x<sjn;x++)
49         {
50             if(cmp(x,y)==true&&dp[y]==1)
51                 dp[y+strlen(sj[x])]=1;
52     /*    for(int k=0;k<l;k++)
53                 printf("%d ",dp[k]);
54             printf("\n");*/
55         }
56         for(x=l;x>=0;x--)
57             if(dp[x]==1)
58                 break;
59             printf("%d\n",x);
60     return 0;
61 }

posted on 2012-06-06 11:23  usp10  阅读(260)  评论(2)    收藏  举报

导航