Codeforces Round #501 (Div. 3) F. Bracket Substring

https://codeforces.com/problemset/problem/1015/F

dp

'求包含某个子串的个数' 类型

kmp

    ///it is advised that all character begins at index 1

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iostream>
 8 using namespace std;
 9 #define ll long long
10 
11 const double eps=1e-8;
12 const ll inf=1e9;
13 const ll mod=1e9+7;
14 const int maxn=2e2+10;
15 
16 char sstr[maxn];
17 
18 int str[maxn],pre[maxn],nex[maxn][2];
19 ll f[maxn][maxn][maxn][2];
20 
21 int main()
22 {
23     int n,nn,len,i,j,k,l,m,jj,lll;
24     scanf("%d",&n);
25     nn=n<<1;
26     ///it is advised that all character begins at index 1
27     scanf("%s",sstr+1);
28     len=strlen(sstr+1);
29     for (i=1;i<=len;i++)
30         if (sstr[i]=='(')
31             str[i]=0;
32         else
33             str[i]=1;
34 
35     ///kmp makes O(1) visit
36     j=0;
37     pre[1]=0;
38     for (i=2;i<=len;i++)
39     {
40         while (j!=0 && str[j+1]!=str[i])
41             j=pre[j];
42         if (str[j+1]==str[i])
43             j++;
44         pre[i]=j;
45     }
46 
47     for (i=0;i<=len-1;i++)
48         for (j=0;j<=1;j++)
49             if (str[i+1]==j)
50                 nex[i][j]=i+1;
51             else
52                 nex[i][j]=nex[pre[i]][j];
53 
54     f[0][0][0][0]=1;
55     ///pos ith
56     for (i=1;i<=nn;i++)
57         ///j '('
58         for (j=0;j<=min(i-1,n);j++)
59             ///current char
60             for (k=0;k<=1;k++)
61             {
62                 jj=j+1+(-2)*(k==1);
63                 if (jj==-1)
64                     continue;
65                 (f[i][jj][0][1]+=f[i-1][j][0][1])%=mod;
66                 ///the lth str
67                 for (l=0;l<=min(len-1,i-1);l++)
68                 {
69                     lll=nex[l][k];
70                     if (lll==len)
71                         (f[i][jj][0][1]+=f[i-1][j][l][0])%=mod;
72                     else
73                         (f[i][jj][lll][0]+=f[i-1][j][l][0])%=mod;
74                 }
75             }
76     printf("%lld",f[nn][0][0][1]);
77     return 0;
78 }
原文地址:https://www.cnblogs.com/cmyg/p/11110273.html