BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
3530: [Sdoi2014]数数
题意:\(\le N\)的不含模式串的数字有多少个,\(n=|N| \le 1200\)
考虑数位DP
对于长度\(\le n\)的,普通套路DP\(g[i][j]\)即可
对于长度\(=n\)的,需要考虑天际线,\(f[i][j][0/1]\)表示从高开始i位走到节点j,是否卡上界的方案数
需要注意的是前导0的处理,不能出现前导0,所以\(f[0]\)往外转移的时候不能走0
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=2005, P=1e9+7;
typedef long long ll;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n, m;
char a[N], s[N];
inline void mod(int &x) {if(x>=P) x-=P;}
namespace ac{
struct meow{int ch[10], fail, val;}t[N];
int sz;
void insert(char *s) {
int len=strlen(s+1), u=0;
for(int i=1; i<=len; i++) {
int c=s[i]-'0';
if(!t[u].ch[c]) t[u].ch[c] = ++sz;
u=t[u].ch[c];
}
t[u].val=1;
}
int q[N], head, tail;
void build() {
head=tail=1;
for(int i=0; i<10; i++) if(t[0].ch[i]) q[tail++]=t[0].ch[i];
while(head!=tail) {
int u=q[head++];
t[u].val |= t[t[u].fail].val;
for(int i=0; i<10; i++) {
int &v=t[u].ch[i];
if(!v) v = t[t[u].fail].ch[i];
else t[v].fail = t[t[u].fail].ch[i], q[tail++]=v;
}
}
}
int f[N][N][2], g[N][N], ans;
void dp() {
g[0][0]=1;
for(int i=0; i<n; i++)
for(int u=0; u<=sz; u++) if(!t[u].val) {
for(int k=0; k<10; k++) if(!t[t[u].ch[k]].val) {
if(i==0 && k==0) continue;
mod(g[i+1][ t[u].ch[k] ] += g[i][u]);
}
}
for(int i=1; i<n; i++) for(int j=0; j<=sz; j++) mod(ans += g[i][j]);
f[0][0][1]=1; //f[0][0][0]=1;
for(int i=0; i<n; i++) { //printf("\niii %d %d\n",i, a[i+1]-'0');
for(int u=0; u<=sz; u++) if(!t[u].val) { //printf("uuu %d %d %d\n",u,f[i][u][0],f[i][u][1]);
for(int k=0; k<10; k++) if(!t[t[u].ch[k]].val) {
if(i==0 && k==0) continue;
int v=t[u].ch[k]; //printf("v %d %d\n",k,v);
mod(f[i+1][v][0] += f[i][u][0]);
if(k < a[i+1]-'0') mod(f[i+1][v][0] += f[i][u][1]);
if(k == a[i+1]-'0') mod(f[i+1][v][1] += f[i][u][1]);
}
}
}
//for(int i=1; i<=n; i++) for(int j=0; j<=sz; j++) printf("f %d %d %d %d\n",i,j,f[i][j][0],f[i][j][1]);
for(int i=0; i<=sz; i++) {
mod(ans += f[n][i][0]);
mod(ans += f[n][i][1]);
}
printf("%d", ans);
}
}
int main() {
freopen("in","r",stdin);
scanf("%s",a+1); n=strlen(a+1);
m=read();
for(int i=1; i<=m; i++) scanf("%s",s+1), ac::insert(s);
ac::build();
ac::dp();
}
BZOJ 3530: [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
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
- 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不是幸运 ...
- [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,输出和 ...
随机推荐
- 0/1背包 dp学习~6
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1203 I NEED A OFFER! Time Limit: 2000/1000 MS (Java/O ...
- Is It A Tree?(并查集)(dfs也可以解决)
Is It A Tree? Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submi ...
- 重新学习一次javascript;
每次有项目的时候,总觉得自己什么都不会做,然后做的时候又很简单,一会就做完了,啪啪打脸: 每次别人问的时候,我知道怎么做,但是不知道具体原理,觉得瞬间low了: 想要好好的吧基础掌握一下: 这几天空闲 ...
- 互联网App应用程序测试流程及测试总结
互联网App应用程序测试流程及测试总结 1. APP测试基本流程 1.1流程图 仍然为测试环境 Pass 1.2测试周期 测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即15个工作日 ...
- 什么是命名空间?php命名空间的基本应用分享
什么是命名空间? php中声明的函数名.类名和常量的名称,在同一次运行中是不能重复的,否则会产生一个致命的错误,常见的解决方法是约定一个前缀.例如 ,在项目开发时,用户 User 模块中的控制器和数据 ...
- UE4 径向模糊radiu blur
hlsl代码为: float2 ScreenMult = ; ; ] = {-0.08,-0.05,-0.03,-0.02,-0.01,0.01,0.02,0.03,0.05,0.08}; float ...
- 算法-java代码实现快速排序
快速排序 对于一个int数组,请编写一个快速排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] ...
- solr单机版安装与基本部署
安装solr准备工作: linux/tomcat/jdk solr单机版的安装 1.解压缩tomcat安装包 tar -zxf tomcat-xxx.tar.gz 2.创建文件夹:mkdir /usr ...
- Oracle:控制语句 IF..ELSIF语句、CASE语句、FOR循环语句
--多重if语句(注意点:BEGIN END ,IF 条件 THEN,ELSIF 条件 THEN,ELSE... END IF)BEGIN IF FALSE THEN DBMS_OUTPUT.put_ ...
- Linux apache的运行用户和用户组
我们在安装apache后,有时在上传文件的时候,提示没有权限或者是不可写,我们都会去查文件夹的权限. 通过ls -l /var/www/html/website可以很直观的看出我们文件和文件夹的权限, ...