• P4052 [JSOI2007]文本生成器


    P4052 [JSOI2007]文本生成器

    AC自动机+dp

    优秀题解传送门

    设f[ i ][ j ]表示串的长度为 i ,当前在 j 点时不可识别的串的方案数

    最后用总方案数减去不可识别方案数就是答案了

    因为题解写的很好所以我就只在代码中加点注释了(逃

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int mod=10007;
    struct data{
        int nxt[26],fail,end;
    }a[6002];
    int n,m,cnt,ans=1,f[102][6002];
    char q[102];
    inline void Trie_build(){
        scanf("%s",q);
        int u=0,len=strlen(q);
        for(int i=0;i<len;++i){
            int p=q[i]-'A';
            if(!a[u].nxt[p]) a[u].nxt[p]=++cnt;
            u=a[u].nxt[p];
        }++a[u].end;
    }
    inline void AC_build(){
        queue <int> h;
        for(int i=0;i<26;++i) if(a[0].nxt[i]) h.push(a[0].nxt[i]);
        while(!h.empty()){
            int x=h.front(); h.pop();
            for(int i=0;i<26;++i){
                int &to=a[x].nxt[i];
                if(to){
                    a[to].fail=a[a[x].fail].nxt[i];
                    a[to].end|=a[a[to].fail].end; //如果该串的后缀是可识别的那么这个串也一定是可识别的
                    h.push(to);
                }else to=a[a[x].fail].nxt[i];
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) Trie_build();
        AC_build();
        f[0][0]=1;
        for(int i=1;i<=m;++i)
            for(int j=0;j<=cnt;++j)
                for(int k=0;k<26;++k)
                    if(!a[a[j].nxt[k]].end) //不可识别
                        f[i][a[j].nxt[k]]=(f[i][a[j].nxt[k]]+f[i-1][j])%mod;
        for(int i=1;i<=m;++i) ans=ans*26%mod;
        for(int i=0;i<=cnt;++i) ans=(ans-f[m][i]+mod)%mod; //总方案数-不可识别方案数
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    如何进行Django单元测试
    django使用celery实现异步操作
    django 多并发,多线程。
    cookies设置时间
    Mysql实现企业级日志管理、备份与恢复
    Redis与Memcached的区别
    cookie 和session 的区别详解
    python内存泄露查找
    浙大月赛ZOJ Monthly, August 2014
    Vector
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9623238.html
Copyright © 2020-2023  润新知