zoukankan      html  css  js  c++  java
  • POJ 1625 Censored!(自动机DP+大数相加)

    题意:给出包含n个可见字符的字符集,以下所提字符串均由该字符集中的字符构成。给出p个长度不超过10的字符串,求长为m且不包含上述p个字符串的字符串有多少个。

    数据范围:1<=n,m<=50,0<=p<=10

    状态设计:dp[i][j],i 步之内未经过危险结点且第 i 步到达结点 j 的路径数目。

    状态转移:dp[i][j]=∑dp[i-1][k],在结点 k 加输入 s[i] 能跳到结点 j

    初始化:dp[0][0]=1,对于其余的 i :dp[0][i]=0

    注意:由于最后结果很大,而题中又没提到取模,所以要用到大数相加。

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    #define NODE 110
    int next[NODE][50];
    int fail[NODE];
    bool flag[NODE];
    int n,L,m,node;
    
    char ch[51];
    
    int dp[51][NODE][100];
    
    int cmp(const void *a,const void *b)
    {
        return *(char*)a-*(char*)b;
    }
    void init()
    {
        node=1;
        memset(next[0],0,sizeof(next[0]));
    }
    void add(int cur,int k)
    {
        memset(next[node],0,sizeof(next[node]));
        flag[node]=0;
        next[cur][k]=node++;
    }
    int hash(char c)
    {
        int min=0,max=n,mid;
        while(min+1!=max)
        {
            mid=min+max>>1;
            if(ch[mid]>c)    max=mid;
            else    min=mid;
        }
        return min;
    }
    void insert(char *s)
    {
        int i,cur,k;
        for(i=cur=0;s[i];i++)
        {
            k=hash(s[i]);
            if(!next[cur][k])   add(cur,k);
            cur=next[cur][k];
        }
        flag[cur]=1;
    }
    void build_ac()
    {
        queue<int>q;
        int cur,nxt,tmp,k;
    
        fail[0]=0;
        q.push(0);
    
        while(!q.empty())
        {
            cur=q.front(),q.pop();
            for(k=0;k<n;k++)
            {
                nxt=next[cur][k];
                if(nxt)
                {
                    if(!cur)    fail[nxt]=0;
                    else
                    {
                        for(tmp=fail[cur];tmp&&!next[tmp][k];tmp=fail[tmp]);
                        fail[nxt]=next[tmp][k];
                    }
                    if(flag[fail[nxt]]) flag[nxt]=1;
                    q.push(nxt);
                }
                else    next[cur][k]=next[fail[cur]][k];
            }
        }
    }
    void ADD(int *a,int *b)
    {
        int i,c=0;
        for(i=0;i<100;i++)
        {
            a[i]+=b[i]+c;
            c=a[i]/10;
            a[i]%=10;
        }
    }
    void solve()
    {
        memset(dp,0,sizeof(dp));
        dp[0][0][0]=1;
    
        for(int step=1;step<=L;step++)
        {
            for(int pre=0;pre<node;pre++)
            {
                if(flag[pre])   continue;
                for(int k=0;k<n;k++)
                {
                    int cur=next[pre][k];
                    if(flag[cur])   continue;
                    ADD(dp[step][cur],dp[step-1][pre]);
                }
            }
        }
    
        int ans[100],i;
        memset(ans,0,sizeof(ans));
        for(i=0;i<node;i++) if(!flag[i])    ADD(ans,dp[L][i]);
    
        for(i=99;i>=0 && ans[i]==0;i--);
        if(i<0) puts("0");
        else
        {
            for(;i>=0;i--)  printf("%d",ans[i]);
            puts("");
        }
    }
    int main()
    {
        char s[51];
        while(~scanf("%d%d%d",&n,&L,&m))
        {
            getchar();
            gets(ch);
            qsort(ch,strlen(ch),sizeof(char),cmp);
    
            init();
            for(int i=0;i<m;i++)
            {
                gets(s);
                insert(s);
            }
            build_ac();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    GTK+ 3.6.2 发布,小的 bug 修复版本
    RunJS 新增 Echo Ajax 测试功能
    Mozilla 发布 Popcorn Maker,在线创作视频
    Sina微博OAuth2框架解密
    Mina状态机State Machine
    Mozilla 发布 Shumway —— 纯JS的SWF解析器
    Code Browser 4.5 发布,代码浏览器
    ROSA 2012 "Enterprise Linux Server" 发布
    ltrace 0.7.0 发布,程序调试工具
    Artifactory 2.6.5 发布,Maven 扩展工具
  • 原文地址:https://www.cnblogs.com/algorithms/p/2628831.html
Copyright © 2011-2022 走看看