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 }

浙公网安备 33010602011771号