• CF1015F Bracket Substring(dp+Trie图)


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

    后者用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
    ",ans);
    79     return 0;
    80 }
  • 相关阅读:
    STM32|4-20mA输出电路
    Delphi版IP地址与整型互转
    侧方位停车
    98年的‘风暴’,08年的‘危机’,18年的“钱荒‘’
    一些软件设计的原则
    oracle-数据库的各种-锁-详解
    演员李艾佳去世突发病征年仅36岁
    【人生】王石:没变强是因为你太舒服
    耐心看的人早晚会成人上人
    Linux之make的用法讲解
  • 原文地址:https://www.cnblogs.com/lnxcj/p/9898004.html
Copyright © 2020-2023  润新知