zoukankan      html  css  js  c++  java
  • BZOJ 3530: [Sdoi2014]数数 AC自动机+dp

    思路不难,但是细节还是挺多的,要格外注意一下. 

    code: 

    #include <cstdio>  
    #include <queue> 
    #include <cstring>   
    #include <algorithm>  
    #define N 2005 
    #define ll long long  
    #define mod 1000000007    
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;
    queue<int>q;  
    char str[N],S[N];           
    int n,m,tot,ch[N][10],f[N],dp[N][N][2],tag[N];  
    void insert() 
    {
        int i,j,len=strlen(str+1),p=0; 
        for(i=1;i<=len;++i) 
        {     
            if(!ch[p][str[i]-'0']) ch[p][str[i]-'0']=++tot;                
            p=ch[p][str[i]-'0'];        
        }   
        tag[p]=1; 
    }         
    void build() 
    {  
        int i,j;                          
        for(i=0;i<10;++i)  if(ch[0][i])  q.push(ch[0][i]);   
        while(!q.empty()) 
        {
            int u=q.front();q.pop();      
            tag[u]|=tag[f[u]];  
            for(i=0;i<10;++i) 
            {
                int qr=ch[u][i]; 
                if(!qr) { ch[u][i]=ch[f[u]][i]; continue; }   
                f[qr]=ch[f[u]][i];     
                q.push(qr);   
            }
        }
    }
    int main() 
    { 
        // setIO("input"); 
        int i,j;              
        scanf("%s%d",S+1,&m);  
        n=strlen(S+1); 
        for(i=1;i<=m;++i)  scanf("%s",str+1),insert(); 
        build();             
        for(i=1;i<S[1]-'0';++i) if(!tag[ch[0][i]]) dp[1][ch[0][i]][0]+=1;        
        if(!tag[ch[0][S[1]-'0']])  dp[1][ch[0][S[1]-'0']][1]=1;   
        for(i=1;i<n;++i) 
        {   
            for(j=1;j<10;++j)  if(!tag[ch[0][j]]) dp[i+1][ch[0][j]][0]+=1;        
            for(j=0;j<=tot;++j) 
            {         
                if(tag[j])  continue;    
                if(dp[i][j][0])  
                {   
                    for(int k=0;k<10;++k)              
                    {
                        if(tag[ch[j][k]]) continue;   
                        (dp[i+1][ch[j][k]][0]+=dp[i][j][0])%=mod; 
                    }
                }           
                if(dp[i][j][1]) 
                {          
                    for(int k=0;k<S[i+1]-'0';++k)    
                    {
                        if(tag[ch[j][k]]) continue;    
                        (dp[i+1][ch[j][k]][0]+=dp[i][j][1]);   
                    }
                }  
                if(tag[ch[j][S[i+1]-'0']])   continue;    
                dp[i+1][ch[j][S[i+1]-'0']][1]|=dp[i][j][1];        
            }
        } 
        int ans=0; 
        for(i=0;i<=tot;++i) 
        {
            if(tag[i]) continue;    
            (ans+=dp[n][i][0])%=mod; 
            (ans+=dp[n][i][1])%=mod;     
        }
        printf("%d
    ",ans); 
        return 0; 
    }
    

      

  • 相关阅读:
    Python学习2——使用字符串(完整版)
    Python补充4——替换与修改
    Python学习3——列表和元组
    数据结构链表——双向链表
    数据结构链表—— 循环链表
    数据结构链表——静态链表
    LeetCode 61——旋转链表(JAVA)
    LeetCode 2——两数相加(JAVA)
    LeetCode 328——奇偶链表(JAVA)
    HillCrest Sensor HAL
  • 原文地址:https://www.cnblogs.com/guangheli/p/12088256.html
Copyright © 2011-2022 走看看