l链接

这题想了好一会呢。。刚开始想错了,以为用自动机预处理出k长度可以包含的合法的数的个数,然后再数位dp一下就行了,写到一半发现不对,还要处理当前走的时候是不是为合法的,这一点无法移到trie树上去判断。

之后想到应该在trie树上进行数位dp,走到第i个节点且长度为j的状态是确定的,所以可以根据trie树上的节点来进行确定状态。

dp[i][j]表示当前节点为i,数第j位时可以包含多少个合法的数。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<stdlib.h>
  7 #include<vector>
  8 #include<cmath>
  9 #include<queue>
 10 #include<set>
 11 using namespace std;
 12 #define N 2010
 13 #define LL long long
 14 #define INF 0xfffffff
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 const int child_num = 2;
 19 const int mod = 1000000009;
 20 int dp[210][N];
 21 char s1[210],s2[210];
 22 class AC
 23 {
 24     private:
 25     int ch[N][child_num];
 26     int Q[N];
 27     int fail[N];
 28     int val[N];
 29     int id[127];
 30     int sz;
 31     int dd[810][N];
 32     public:
 33     void init()
 34     {
 35         fail[0] = 0;
 36         id['0'] = 0;id['1'] = 1;
 37     }
 38     void reset()
 39     {
 40         memset(val,0,sizeof(val));
 41         memset(ch[0],0,sizeof(ch[0]));
 42         sz=1;
 43     }
 44     void insert(char *a,int key)
 45     {
 46         int p =0 ;
 47         for( ; *a ; a++)
 48         {
 49             int d = id[*a];
 50             if(ch[p][d]==0){
 51                 memset(ch[sz],0,sizeof(ch[sz]));
 52                 ch[p][d] = sz++;
 53             }
 54             p = ch[p][d];
 55         }
 56         val[p] = key;
 57     }
 58     void construct()
 59     {
 60         int i,head=0,tail = 0;
 61         for(i = 0 ;i < child_num ; i++)
 62         {
 63             if(ch[0][i])
 64             {
 65                 fail[ch[0][i]] = 0;
 66                 Q[tail++] = ch[0][i];
 67             }
 68         }
 69         while(head!=tail)
 70         {
 71             int u = Q[head++];
 72             val[u]|=val[fail[u]];
 73             for(i =0 ;i < child_num ; i++)
 74             {
 75                 if(ch[u][i])
 76                 {
 77                     fail[ch[u][i]] = ch[fail[u]][i];
 78                     Q[tail++] = ch[u][i];
 79                 }
 80                 else ch[u][i] = ch[fail[u]][i];
 81             }
 82         }
 83     }
 84     int dfs(char *s,int i,int c,int e,int k)
 85     {
 86         if(i==-1)
 87         {
 88             return 1;
 89         }
 90         if(!e&&~dp[i][c])
 91         {
 92             return dp[i][c];
 93         }
 94         int mk = e?s[i]-'0':9;
 95         int ans = 0;
 96         for(int j = 0; j <= mk ; j++)
 97         {
 98             if(!k&&j==0&&i)
 99             {
100                 ans = (ans+dfs(s,i-1,c,e&&j==mk,k));
101                 continue;
102             }
103             int p = c,flag = 1;
104             for(int g = 3; g >=0 ; g--)
105             {
106                 int o = (j&(1<<g))?1:0;
107                 p = ch[p][o];
108                 int tmp = p;
109                 while(tmp!=0)
110                 {
111                     if(val[tmp])
112                     {
113                         flag = 0;
114                         break;
115                     }
116                     tmp = fail[tmp];
117                 }
118                 if(!flag) break;
119             }
120             if(flag)
121             {
122                 ans = (ans+dfs(s,i-1,p,e&&j==mk,1))%mod;
123             }
124         }
125         return e?ans:dp[i][c] = ans;
126     }
127     void work(char *s1,char *s2)
128     {
129         memset(dp,-1,sizeof(dp));
130         printf("%d\n",(dfs(s2,strlen(s2)-1,0,1,0)-dfs(s1,strlen(s1)-1,0,1,0)+mod)%mod);
131     }
132 }ac;
133 char vir[22];
134 char ss1[210],ss2[210];
135 int main()
136 {
137     int t,n,i;
138     ac.init();
139     scanf("%d",&t);
140     while(t--)
141     {
142         ac.reset();
143         scanf("%d",&n);
144         while(n--)
145         {
146             scanf("%s",vir);
147             ac.insert(vir,1);
148         }
149         ac.construct();
150         scanf("%s%s",s1,s2);
151         int k = strlen(s1),kk= strlen(s2);
152         for(i = k-1 ; i >= 0; i--)
153         {
154             if(s1[i]>'0')
155             {
156                 s1[i]-=1;
157                 break;
158             }
159             else
160             s1[i] = '9';
161         }
162         for(i = 0; i < k ; i++)
163         ss1[k-1-i] = s1[i];
164         ss1[k] = '\0';
165         for(i = 0; i < kk ; i++)
166         ss2[kk-1-i] = s2[i];
167         ss2[kk] = '\0';
168         ac.work(ss1,ss2);
169     }
170     return 0;
171 }

View Code

转载于:https://www.cnblogs.com/shangyu/p/3750828.html

zoj3494BCD Code(ac自动机+数位dp)相关推荐

  1. ZOJ-3494 BCD Code (ac自动机+数位dp)

    题目链接 Problem Description Binary-coded decimal (BCD) is an encoding for decimal numbers in which each ...

  2. 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)

    3530: [Sdoi2014]数数 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 682  Solved: 364 Description 我们称 ...

  3. 【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp

    题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...

  4. 【BZOJ3530】数数(SDOI2014)-AC自动机+数位DP

    测试地址:数数 做法:本题需要用到AC自动机+数位DP. 首先看到多模式串匹配,自然想到用AC自动机来做.用AC自动机构造出状态转移图后,令f(i,j,k)f(i,j,k)f(i,j,k)为匹配了最高 ...

  5. Censored! POJ - 1625 AC自动机+大数DP

    题意: 给出一n种字符的字典,有p个禁用的单词, 问能组成多少个不同的长度为m的合法字符串.(m<=50) 题解: 是不是个我们之前做的题目非常非常像,题意都一样. 直接将上次写的AC自动机+矩 ...

  6. AC自动机 + 概率dp + 高斯消元 --- HDU 5955 or 2016年沈阳icpc H [AC自动机 + 概率dp + 高斯消元]详解

    题目链接 题目大意: 就是有NNN个人,每个人都会猜一个长度为LLL的只包含{1,2,3,4,5,6}\{1,2,3,4,5,6\}{1,2,3,4,5,6}的序列,现在裁判开始投掷骰子,并且把每次的 ...

  7. HDU3247 Resource Archiver(AC自动机+BFS+DP)

    题目,求最短的包含所有n个DNA片段且不包含任何一个病毒片段的序列. 容易用所有DNA片段和病毒片段建一个AC自动机,构造fail时处理一下各个结点后缀是DNA或者病毒的情况,然后dp[S][u]表示 ...

  8. 【BZOJ2553】禁忌,AC自动机+期望DP+矩乘

    传送门 先考虑选最多禁忌串的问题 感受一下,如果禁忌串之间没有包含关系,一定是可以从前往后贪心搞的,直接建AC自动机跑匹配,找到一个禁忌串的末尾就回到根上,并把禁忌串数量+1 (所以起初我想的是把包含 ...

  9. POJ 1625 Censored! (AC自动机 + 高精度 + DP)

    题目链接:Censored! 解析:AC自动机 + 高精度 + 简单DP. 字符有可能会超过128,用map映射一下即可. 中间的数太大,得上高精度. 用矩阵快速幂会超时,简单的DP就能解决时间的问题 ...

最新文章

  1. 如何提升研发人员的非技术才能
  2. linux下 mysql 的root用户忘记密码解决方案
  3. 单线程实现并发——协程,gevent模块
  4. 如何给BSP application创建指定的mime resource
  5. 想建一个带分隔条的label 控件;
  6. 千图成像python_吞了1000瓶老干妈的南山头铁鹅,Python制作千图成像(附上源代码和应用程序)...
  7. Hack the box -- 靶机渗透测试(TIER2)
  8. 修复被破坏了的linux文件系统分区表,修复被破坏了的linux文件系统分区表
  9. 现货黄金与白银现货的区别
  10. 一篇博客解决网线挑选问题
  11. Matlab中读取excel表格数据
  12. python模拟足球射门_用Python模拟2018世界杯夺冠之路
  13. 判断等腰三角形java_JAVA怎么编写程序判断一个三角形是否为等腰三角形
  14. Android获取歌曲详细信息
  15. php怎么判断qq内置浏览器,如何判断微信内置浏览器(JS PHP)
  16. 删除压缩包密码的方式有几种?
  17. 图神经网络论文阅读(九) Break the Ceiling: Stronger Multi-scale Deep Graph Convolutional Networks,NeurIPS2019
  18. 卡尔曼滤波做轨迹预测
  19. 拒绝破解 用10大免费软件来代替盗版
  20. sql注入php代码审计1

热门文章

  1. HDU ACM 1224 Free DIY Tour (SPFA)
  2. Session保存到Memcache
  3. OUTLOOK 的PST文件和OST文件的区别
  4. python替代goto_如何在 Python 中实现 goto 语句
  5. php 滑动 图片,JQuery图片滑动
  6. H3C服务器系统配置ip,H3C交换机DHCP 服务器动态分配地址典型配置指导
  7. Dijkstra(迪杰斯特拉)算法的总结
  8. cordova指定版本_Cordova/Ionic构建android Gradle错误:支持的最小Gradle版本是2.14.1。当前版本是2.13...
  9. 法国计算机科学专业大学排名,法国计算机视觉专业大学排名(2020年USNEWS)_快飞留学...
  10. 解决centos sudo执行仍旧显示Permission denied