码迷,mamicode.com
首页 > 其他好文 > 详细

CF1015F Bracket Substring(dp+Trie图)

时间:2018-11-02 20:30:09      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:code   scanf   bsp   序列   子序列   ack   ring   \n   def   

用所有合法序列的方案数减不包含题目中要求的子序列的合法序列数

后者用AC自动机维护一下dp就好

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define mod 1000000007
 6 using namespace std;
 7 int n,m,cnt,tot,minu,ans;
 8 char son[205];
 9 int al[205][105];
10 int dp[205][205][105];
11 int ed[205];
12 int tr[205][2];
13 int fail[205];
14 void build(char b[]){
15     int now=0;
16     int len=strlen(b+1);
17     for(int i=1;i<=len;i++){
18         int k=-1;
19         if(b[i]==()k=1;
20         else k=0;
21         if(!tr[now][k])tr[now][k]=++cnt;
22         now=tr[now][k];
23     }
24     ed[now]=1;
25 }
26 void getfail(){
27     queue<int>que;
28     int now=0;
29     if(tr[0][0])que.push(tr[0][0]);
30     if(tr[0][1])que.push(tr[0][1]);
31     while(!que.empty()){
32         int s=que.front();
33         que.pop();
34         if(tr[s][0]){
35             fail[tr[s][0]]=tr[fail[s]][0];
36             que.push(tr[s][0]);
37         }else{
38             tr[s][0]=tr[fail[s]][0];
39         }
40         if(tr[s][1]){
41             fail[tr[s][1]]=tr[fail[s]][1];
42             que.push(tr[s][1]);
43         }else{
44             tr[s][1]=tr[fail[s]][1];
45         }
46     }
47 }
48 int main(){
49     scanf("%d",&n);
50     scanf("%s",son+1);
51     build(son);
52     getfail();
53     al[1][1]=1;
54     for(int i=2;i<=2*n;i++){
55         for(int j=0;j<=n;j++){
56             (al[i][j]+=al[i-1][j+1])%=mod;
57             if(j)(al[i][j]+=al[i-1][j-1])%=mod;
58         }
59     }
60     tot=al[2*n][0];
61     dp[0][0][0]=1;
62     for(int i=1;i<=2*n;i++){
63         for(int j=0;j<=cnt;j++){
64             for(int k=0;k<=n;k++){
65                 if(!ed[tr[j][0]]){
66                     (dp[i][tr[j][0]][k]+=dp[i-1][j][k+1])%=mod;
67                 }
68                 if(!ed[tr[j][1]]&&k){
69                     (dp[i][tr[j][1]][k]+=dp[i-1][j][k-1])%=mod;
70                 }
71             }
72         }
73     }
74     for(int i=0;i<cnt;i++){
75         (minu+=dp[2*n][i][0])%=mod;
76     }
77     ans=((tot-minu)%mod+mod)%mod;
78     printf("%d\n",ans);
79     return 0;
80 }

 

CF1015F Bracket Substring(dp+Trie图)

标签:code   scanf   bsp   序列   子序列   ack   ring   \n   def   

原文地址:https://www.cnblogs.com/lnxcj/p/9898004.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!