zoukankan      html  css  js  c++  java
  • bzoj 3530 : [Sdoi2014]数数

      一眼AC自动机上DP,f[i][j][0]到第j个节点表示前i位与n一样的方案,1表示不一样的方案。

      事实证明我每回写数位dp都要wa到神志模糊,数据一有0就跪,所以加了各种特判。。。

      因为如果数据中有0032这种的话直接dp会把32判为不合法,而事实上它是合法的,因为要去掉前缀0.

      所以每回从根向0的边转移时要少转移1,相当于把0000....这个全为0的前缀保留在根,为了保留这个前缀还要从第二次开始每次f[i][0][1]++。

      好像每次写数位dp都是加了一堆特判才过的。。。

      

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<queue>
      5 #include<algorithm>
      6 #define p 1000000007
      7 using namespace std;
      8 int m,n;
      9 char s[2000];
     10 int ch[2000][10];int cnt;
     11 bool v[2000];
     12 bool flag;
     13 void build()
     14 {
     15     int len=strlen(s);
     16     int now=0;
     17     for(int i=0;i<len;i++)
     18     {
     19         int c=s[i]-'0';
     20         if(ch[now][c])now=ch[now][c];
     21         else
     22         {
     23             ch[now][c]=++cnt;
     24             now=ch[now][c];
     25         }
     26     }
     27     v[now]=1;
     28 }
     29 queue<int>q;
     30 int f[2000];
     31 int ans;
     32 void AC()
     33 {
     34     for(int i=0;i<10;i++)
     35     {
     36         if(ch[0][i])q.push(ch[0][i]);
     37     }
     38     while(!q.empty())
     39     {
     40         int tmp=q.front();q.pop();
     41         for(int i=0;i<10;i++)
     42         {
     43             if(ch[tmp][i])
     44             {
     45                 f[ch[tmp][i]]=ch[f[tmp]][i];
     46                 q.push(ch[tmp][i]); 
     47                 if(v[f[ch[tmp][i]]])v[ch[tmp][i]]=1;
     48             }
     49             else
     50             {
     51                 ch[tmp][i]=ch[f[tmp]][i];
     52             }
     53         }
     54     }
     55 }
     56 int now[2000][2],pre[2000][2];
     57 char a[2000];
     58 int be[2000];
     59 int main()
     60 {
     61     scanf("%s",a);
     62     n=strlen(a);
     63     scanf("%d",&m);
     64     for(int i=1;i<=m;i++)
     65     {
     66         scanf("%s",s);
     67         build();
     68     }
     69     AC();
     70     pre[0][0]=1;
     71     for(int i=0;i<n;i++)
     72     {
     73         int x=a[i]-'0';
     74         if(i)pre[0][1]++;
     75         for(int j=0;j<=cnt;j++)
     76         {
     77             if(v[j])continue;
     78             for(int k=0;k<x;k++)
     79             {
     80                 if(!i&&!k)continue;
     81                 now[ch[j][k]][1]+=pre[j][0];
     82                 now[ch[j][k]][1]%=p;
     83             }
     84             now[ch[j][x]][0]+=pre[j][0];
     85             now[ch[j][x]][0]%=p;
     86             for(int k=0;k<10;k++)
     87             {
     88                 now[ch[j][k]][1]+=pre[j][1]-(!j&&k==0&&i!=0);
     89                 now[ch[j][k]][1]%=p;
     90             }
     91         }
     92         for(int j=0;j<=cnt;j++)
     93         {
     94             if(v[j])continue;
     95             if(i==n-1)
     96             {
     97                 ans+=now[j][1];
     98                 if(ans>=p)ans-=p;
     99                 ans+=now[j][0];
    100                 if(ans>=p)ans-=p;
    101             }
    102             pre[j][0]=now[j][0];
    103             pre[j][1]=now[j][1];
    104             now[j][0]=now[j][1]=0;
    105         }
    106     }
    107     printf("%d
    ",ans);
    108     return 0;
    109 }
  • 相关阅读:
    104.Maximum Depth of Binary Tree
    103.Binary Tree Zigzag Level Order Traversal
    102.Binary Tree Level Order Traversal
    101.Symmetric Tree
    100.Same Tree
    99.Recover Binary Search Tree
    98.Validate Binary Search Tree
    97.Interleaving String
    static静态初始化块
    serialVersionUID作用
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6435963.html
Copyright © 2011-2022 走看看