zoj3494BCD Code(ac自动机+数位dp)
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)相关推荐
- ZOJ-3494 BCD Code (ac自动机+数位dp)
题目链接 Problem Description Binary-coded decimal (BCD) is an encoding for decimal numbers in which each ...
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 682 Solved: 364 Description 我们称 ...
- 【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
- 【BZOJ3530】数数(SDOI2014)-AC自动机+数位DP
测试地址:数数 做法:本题需要用到AC自动机+数位DP. 首先看到多模式串匹配,自然想到用AC自动机来做.用AC自动机构造出状态转移图后,令f(i,j,k)f(i,j,k)f(i,j,k)为匹配了最高 ...
- Censored! POJ - 1625 AC自动机+大数DP
题意: 给出一n种字符的字典,有p个禁用的单词, 问能组成多少个不同的长度为m的合法字符串.(m<=50) 题解: 是不是个我们之前做的题目非常非常像,题意都一样. 直接将上次写的AC自动机+矩 ...
- 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}的序列,现在裁判开始投掷骰子,并且把每次的 ...
- HDU3247 Resource Archiver(AC自动机+BFS+DP)
题目,求最短的包含所有n个DNA片段且不包含任何一个病毒片段的序列. 容易用所有DNA片段和病毒片段建一个AC自动机,构造fail时处理一下各个结点后缀是DNA或者病毒的情况,然后dp[S][u]表示 ...
- 【BZOJ2553】禁忌,AC自动机+期望DP+矩乘
传送门 先考虑选最多禁忌串的问题 感受一下,如果禁忌串之间没有包含关系,一定是可以从前往后贪心搞的,直接建AC自动机跑匹配,找到一个禁忌串的末尾就回到根上,并把禁忌串数量+1 (所以起初我想的是把包含 ...
- POJ 1625 Censored! (AC自动机 + 高精度 + DP)
题目链接:Censored! 解析:AC自动机 + 高精度 + 简单DP. 字符有可能会超过128,用map映射一下即可. 中间的数太大,得上高精度. 用矩阵快速幂会超时,简单的DP就能解决时间的问题 ...
最新文章
- 如何提升研发人员的非技术才能
- linux下 mysql 的root用户忘记密码解决方案
- 单线程实现并发——协程,gevent模块
- 如何给BSP application创建指定的mime resource
- 想建一个带分隔条的label 控件;
- 千图成像python_吞了1000瓶老干妈的南山头铁鹅,Python制作千图成像(附上源代码和应用程序)...
- Hack the box -- 靶机渗透测试(TIER2)
- 修复被破坏了的linux文件系统分区表,修复被破坏了的linux文件系统分区表
- 现货黄金与白银现货的区别
- 一篇博客解决网线挑选问题
- Matlab中读取excel表格数据
- python模拟足球射门_用Python模拟2018世界杯夺冠之路
- 判断等腰三角形java_JAVA怎么编写程序判断一个三角形是否为等腰三角形
- Android获取歌曲详细信息
- php怎么判断qq内置浏览器,如何判断微信内置浏览器(JS PHP)
- 删除压缩包密码的方式有几种?
- 图神经网络论文阅读(九) Break the Ceiling: Stronger Multi-scale Deep Graph Convolutional Networks,NeurIPS2019
- 卡尔曼滤波做轨迹预测
- 拒绝破解 用10大免费软件来代替盗版
- sql注入php代码审计1
热门文章
- HDU ACM 1224 Free DIY Tour (SPFA)
- Session保存到Memcache
- OUTLOOK 的PST文件和OST文件的区别
- python替代goto_如何在 Python 中实现 goto 语句
- php 滑动 图片,JQuery图片滑动
- H3C服务器系统配置ip,H3C交换机DHCP 服务器动态分配地址典型配置指导
- Dijkstra(迪杰斯特拉)算法的总结
- cordova指定版本_Cordova/Ionic构建android Gradle错误:支持的最小Gradle版本是2.14.1。当前版本是2.13...
- 法国计算机科学专业大学排名,法国计算机视觉专业大学排名(2020年USNEWS)_快飞留学...
- 解决centos sudo执行仍旧显示Permission denied