几道用到KMP的DP题:

hdu 5763    hdu 3689    hdu 3336    codeforces 494B    codevs 3945

关于KMP的nx数组:

如果在本文中看见了nx[]指的是所谓“成功指针”,或者getnx()函数跟本人之前的板子写的不一样......

都是因为求nx数组有两种方法!!!

详情请阅本人的另一篇文章:关于KMP算法的重大发现

好了我们进入正题~

一道一道来~

hdu 5763  Another Meaning

题意及样例:原题链接

设第一个串为A,长为n;第二个串为B,长为L

从1到n计算1~k能代表的意思的数量f[k]

如果A[k-L+1,k]==B

则f[k]=f[k-L]+f[k-1]

否则f[k]=f[k-1]

判断A[k-L+1,k]是否与B匹配就要靠KMP了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define mod 1000000007
 5 using namespace std;
 6 
 7 int t,al,bl;
 8 char a[100005];
 9 char b[100005];
10 int nx[100005];
11 int fl[100005];
12 int f[100005]; 
13 
14 void getnx()
15 {
16     nx[1]=0;
17     for(int i=2,j=1;i<=bl;)
18     {
19         nx[i]=j;
20         while(j&&b[j]!=b[i])j=nx[j];
21         j++,i++;
22     }
23 }
24 
25 void kmp()
26 {
27     for(int i=1,j=1;i<=al;)
28     {
29         while(j&&b[j]!=a[i])j=nx[j];
30         if(j==bl)
31         {
32             fl[i]=1;
33             j=nx[j];
34         }
35         else j++,i++;
36     }
37 }
38 
39 int main()
40 {
41     scanf("%d",&t);
42     for(int cs=1;cs<=t;cs++)
43     {
44         memset(a,0,sizeof(a));
45         memset(b,0,sizeof(b));
46         memset(fl,0,sizeof(fl));
47         scanf("%s",a+1);
48         scanf("%s",b+1);
49         al=strlen(a+1);
50         bl=strlen(b+1);
51         getnx();
52         kmp();
53         f[0]=1;
54         for(int i=1;i<=al;i++)
55         {
56             if(fl[i])f[i]=(f[i-1]+f[i-bl])%mod;
57             else f[i]=f[i-1];
58         }
59         printf("Case #%d: %d\n",cs,f[al]);
60     }
61     return 0;
62 }
hdu 5763 Another Meaning

相关文章: