• bzoj 1030 文本生成器


    题目大意:

    生成一个长度为n的字符串,使它包含给出串中的一个

    求这个生成串的方案数

    思路:

    dp i j表示匹配到i位,trie树上第j个节点的方案数

    可以得到dp方程,dp i j 可以转移到 dp i+1 ch[j] 

    记录一下结尾处的节点

    然后用总方案数-所有匹配不到的

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 6010
    12 #define MOD 10007
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int n,dp[110][MAXN],m,tot,sz,ans;
    22 char s[110];
    23 bool ed[MAXN];
    24 struct Trie {int fail,ch[26];}tr[MAXN];
    25 void insert(char *c,int len)
    26 {
    27     int pos=0;
    28     for(int i=1;i<=len;i++)
    29     {
    30         if(!tr[pos].ch[c[i]-'A']) tr[pos].ch[c[i]-'A']=++sz;
    31         pos=tr[pos].ch[c[i]-'A'];
    32     }
    33     ed[pos]=1;
    34 }
    35 void build()
    36 {
    37     queue <int> q;
    38     for(int i=0;i<26;i++) if(tr[0].ch[i]) q.push(tr[0].ch[i]);
    39     while(!q.empty())
    40     {
    41         int k=q.front();q.pop();
    42         for(int i=0;i<26;i++)
    43             if(tr[k].ch[i]) tr[tr[k].ch[i]].fail=tr[tr[k].fail].ch[i],q.push(tr[k].ch[i]);
    44             else tr[k].ch[i]=tr[tr[k].fail].ch[i];
    45         ed[k]+=ed[tr[k].fail];
    46     }
    47 }
    48 int main()
    49 {
    50     n=read(),m=read();
    51     for(int i=1;i<=n;i++) scanf("%s",s+1),insert(s,strlen(s+1));
    52     build();
    53     dp[0][0]=tot=1;
    54     for(int i=1;i<=m;i++) (tot*=26)%=MOD;
    55     for(int i=1;i<=m;i++)
    56         for(int j=0;j<=sz;j++)
    57         {
    58             if(ed[j]) continue;
    59             for(int k=0;k<26;k++) (dp[i][tr[j].ch[k]]+=dp[i-1][j])%=MOD;
    60         }
    61     for(int i=0;i<=sz;i++) if(!ed[i]) (ans+=dp[m][i])%=MOD;
    62     printf("%d",(tot-ans+MOD)%MOD);
    63 }
    View Code

     orz没写主函数里忘了写build调了一年

  • 相关阅读:
    AppleID的双重认证
    swift 分组tableview 设置分区投或者尾部,隐藏默认间隔高度
    swift 警告框
    数组
    循环结构(二)
    循环结构
    选择结构
    选择结构
    变量 数据类型和运算符
    (五)Spring 中的 aop
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8252579.html
Copyright © 2020-2023  润新知