【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp
题目描述
我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串。例如当S=(22,333,0233)时,233是幸运数,2333、20233、3223不是幸运数。
给定N和S,计算不大于N的幸运数个数。
输入
输入的第一行包含整数N。
接下来一行一个整数M,表示S中元素的数量。
接下来M行,每行一个数字串,表示S中的一个元素。
输出
输出一行一个整数,表示答案模109+7的值。
样例输入
20
3
2
3
14
样例输出
14
题解
AC自动机+数位dp
同学的某道考试题的加强版。。。
由于给定的串多且复杂,要求不能匹配到这些串,所以可以对这些串建立Trie图。
然后设$f[i][j]$表示从$j$开始走$i$个节点,不触碰到危险节点(即得到的是非幸运数)的方案数。
那么如果$j$是危险节点则方案数为0,否则枚举$j$走出去的第一步,用$f[i-1][next[j][k]]$更新$f[i][j]$。
考虑数位dp的过程:
首先处理出位数不满$n$位的数的个数:枚举位数和最高位(非0),然后方案数即为$f[i][next[1][j]]$。
然后考虑位数满$n$位的数的个数:
考虑从高到底的每一位:从0到当前位-1是满的(即后面的数恰好从0到10^{位数}),因此可以直接从$f$中取出。再考虑当前位不满的情况,此时转化为了子问题,按照同样的方法处理即可。
注意最高位是不能包含前导0的,而确定最高位以后其余的位是可以包含前导0的。
时间复杂度$O(10nL)$
细节贼多。。。代码凑合着看吧。。。
#include <queue>
#include <cstdio>
#include <cstring>
#define N 1510
#define mod 1000000007
using namespace std;
queue<int> q;
int next[N][10] , tot = 1 , fail[N] , tag[N] , f[N][N];
char s[N] , w[N];
void build()
{
int x , i;
for(i = 0 ; i < 10 ; i ++ ) next[0][i] = 1;
q.push(1);
while(!q.empty())
{
x = q.front() , q.pop() , tag[x] |= tag[fail[x]];
for(i = 0 ; i < 10 ; i ++ )
{
if(next[x][i]) fail[next[x][i]] = next[fail[x]][i] , q.push(next[x][i]);
else next[x][i] = next[fail[x]][i];
}
}
}
int main()
{
int n , m , i , j , k , t , flag , ans = 0;
scanf("%s%d" , s , &m) , n = strlen(s);
for(i = 1 ; i <= m ; i ++ )
{
scanf("%s" , w);
for(j = 0 , t = 1 ; w[j] ; j ++ )
{
if(!next[t][w[j] ^ '0']) next[t][w[j] ^ '0'] = ++tot;
t = next[t][w[j] ^ '0'];
}
tag[t] = 1;
}
build();
for(i = 1 ; i <= tot ; i ++ ) f[1][i] = !tag[i];
for(i = 2 ; i <= n ; i ++ )
for(j = 1 ; j <= tot ; j ++ )
if(!tag[j])
for(k = 0 ; k < 10 ; k ++ )
f[i][j] = (f[i][j] + f[i - 1][next[j][k]]) % mod;
for(i = 1 ; i < n ; i ++ )
for(j = 1 ; j < 10 ; j ++ )
ans = (ans + f[i][next[1][j]]) % mod;
for(i = 0 , t = flag = 1 ; i < n ; i ++ )
{
for(j = flag ; j < (s[i] ^ '0') ; j ++ ) ans = (ans + f[n - i][next[t][j]]) % mod;
t = next[t][s[i] ^ '0'];
if(tag[t]) break;
flag = 0;
}
if(!tag[t]) ans = (ans + 1) % mod;
printf("%d\n" , ans);
return 0;
}
【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp的更多相关文章
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 682 Solved: 364 Description 我们称一 ...
- 【JZOJ3624】【SDOI2014】数数(count) AC自动机+数位dp
题面 100 容易想到使用AC自动机来处理禁忌子串的问题: 然后在自动机上数位dp,具体是: \(f_{i,j,0/1}\)表示填了\(i\)位,当前在自动机的第\(j\)个结点上,\(0\)表示当前 ...
- BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)
题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...
- BZOJ3530:[SDOI2014]数数(AC自动机,数位DP)
Description 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3 ...
- BZOJ3530[Sdoi2014]数数——AC自动机+数位DP
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
- BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
3530: [Sdoi2014]数数 题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\) 考虑数位DP 对于长度\(\le n\)的,普通套路DP\(g[i][j ...
- [SDOI2014]数数 --- AC自动机 + 数位DP
[SDOI2014]数数 题目描述: 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串. 例如当S=(22,333,0233)时,233是幸运数,2333 ...
- P3311 [SDOI2014]数数 AC自动机+数位DP
题意 给定一个正整数N和n个模式串,问不大于N的数字中有多少个不包含任意模式串,输出对\(1e^9+7\)取模后的答案. 解题思路 把所有模式串都加入AC自动机,然后跑数位DP就好了.需要注意的是,这 ...
- HDU-4518 吉哥系列故事——最终数 AC自动机+数位DP
题意:如果一个数中的某一段是长度大于2的菲波那契数,那么这个数就被定义为F数,前几个F数是13,21,34,55......将这些数字进行编号,a1 = 13, a2 = 21.现给定一个数n,输出和 ...
随机推荐
- javascript入门笔记7-计时器
计时器 语法: setInterval(代码,交互时间) 参数说明: 代码:要调用的函数或要执行的代码串. 交互时间:周期性执行或调用表达式之间的时间间隔,以毫秒计(1s=1000ms). 例子: & ...
- 2017年10月26日 git上传文件失败的文件
最近几天因为项目要用git,于是学习了一下git.今天上传项目到码云的时候,却发现总有一些文件夹上传不上去,git 也显示everything is update.找了一圈办法,都没有用,最后突然发现 ...
- (排班表三)导出列名不固定的Grid表格到Excel
将班表信息导出Excel表格保存到本地 要求:文档名称为[XXXX]年X月值班表 文档显示的效果: 实现代码: //导出Excel值班表 private void btn_export_1_Click ...
- javascript遍历方法总结
forEach 循环 JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for (var index = 0; index < myArray.lengt ...
- 前端调试vConsole
在移动端开发的时候,有时候需要真机调试的时候,没法看到console输出的信息,所以就有这个vConsole的开源插件 很方便就可以查看console输出的信息. 官方地址:https://www.n ...
- strak组件(5):为列表定制预留钩子方法
效果图: 新增函数 def get_list_display(self): 获取页面上应该显示的列,预留的自定义扩展,例如:以后根据用户的不同显示不同的 一.stark组件 stark/servic ...
- Linux基础知识与命令1(su passwd)
一.Linux的基本原则 1.linux由一个个目的单一的小程序组成,我们一般需要组合小程序来完成复杂的任务 2.Linux的一切都是文件(文件类似于一棵树,包括外设,接口) 3.Linux尽量避免捕 ...
- Triangular Sums 南阳acm122
Triangular Sums 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 The nth Triangular number, T(n) = 1 + … + n ...
- POJ:2229-Sumsets(完全背包的优化)
题目链接:http://poj.org/problem?id=2229 Sumsets Time Limit: 2000MS Memory Limit: 200000K Total Submissio ...
- zeppelin的数据集的优化
前面我们介绍了zeppelin的修改,前面由于自己的原因,对zeppelin的修改过于多,现在由于优化了,我们两个类, 一个是zeppelin-server的NotebookServer的类的broa ...