Description

我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串。例如当S=(22,333,0233)时,233是幸运数,2333、20233、3223不是幸运数。
    给定N和S,计算不大于N的幸运数个数。

Input

输入的第一行包含整数N。
    接下来一行一个整数M,表示S中元素的数量。
    接下来M行,每行一个数字串,表示S中的一个元素。

Output

输出一行一个整数,表示答案模109+7的值。

Sample Input

20
3
2
3
14

Sample Output

14

解题思路:

很明显是个数位Dp,相当于n位的不要62,由于不要62的字符个数是可以枚举的,这个不可以。

设计一个状态dp[i][j][onlim(0/1)][zero(0/1)]来表示字符到了 i 位,Trie图上到了 j 号节点,是否压了上线,是否有前导零。

转移则是寻找Trie图上一个子节点,如果不代表字符的结束,那么进一位,判断是否压上界,是否为零即可。

注意子节点为root时不向下转移Trie图(即失配)

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
const lnt mod=(lnt)(1e9+);
struct trnt{
int ch[];
int fl;
bool fin;
}tr[];
class queue{
public:
queue(void){h=,t=;return ;}
int nxt(int x){if(x+==)return ;return x+;}
int front(void){return line[h];}
void pop(void){h=nxt(h);return ;}
void push(int x){t=nxt(t);line[t]=x;return ;}
bool empty(void){return nxt(t)==h;}
private:
int h,t,line[];
}Q;
int siz;
int n,m;
int l;
char tmp[];
int num[];
lnt dp[][][][];
void Insert(char *a)
{
int root=;
int len=strlen(a+);
for(int i=;i<=len;i++)
{
int c=a[i]-'';
if(!tr[root].ch[c])
tr[root].ch[c]=++siz;
root=tr[root].ch[c];
}
tr[root].fin=true;
return ;
}
void Build(void)
{
int root=;
for(int i=;i<;i++)
if(tr[root].ch[i])
Q.push(tr[root].ch[i]);
while(!Q.empty())
{
root=Q.front();
Q.pop();
tr[root].fin|=tr[tr[root].fl].fin;
for(int i=;i<;i++)
if(tr[root].ch[i])
{
tr[tr[root].ch[i]].fl=tr[tr[root].fl].ch[i];
Q.push(tr[root].ch[i]);
}else
tr[root].ch[i]=tr[tr[root].fl].ch[i];
}
return ;
}
int main()
{
scanf("%s",tmp+);
l=strlen(tmp+);
for(int i=;i<=l;i++)
num[i]=tmp[i]-'';
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%s",tmp+);
Insert(tmp);
}
Build();
dp[][][][]=;
for(int i=;i<=l;i++)
{
for(int j=;j<=siz;j++)
{
for(int onlim=;onlim<;onlim++)
{
for(int zero=;zero<;zero++)
{
if(!dp[i-][j][onlim][zero])
continue;
int lim=onlim*num[i]+(-onlim)*;
for(int c=;c<=lim;c++)
{
if(tr[tr[j].ch[c]].fin)
continue;
int nwlim=onlim&&(c==lim);
int nwzro=zero&&(!c);
int nwplc=(-nwzro)*tr[j].ch[c];
dp[i][nwplc][nwlim][nwzro]=(dp[i][nwplc][nwlim][nwzro]+dp[i-][j][onlim][zero])%mod;
}
}
}
}
}
lnt ans=;
for(int i=;i<=siz;i++)
ans=(ans+dp[l][i][][]+dp[l][i][][])%mod;
printf("%lld\n",(ans+mod)%mod);
return ;
}

BZOJ3530: [Sdoi2014]数数(Trie图,数位Dp)的更多相关文章

  1. BZOJ_3209_花神的数论题_组合数+数位DP

    BZOJ_3209_花神的数论题_组合数+数位DP Description 背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 描述 话说花神这天又 ...

  2. [bzoj3530][Sdoi2014]数数_AC自动机_数位dp

    数数 bzoj-3530 Sdoi-2014 题目大意:给你一个整数集合,求所有不超过n的正整数,是的它的十进制表示下不能再一段等于集合中的任意数. 注释:$1\le n \le 1200$,$1\l ...

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

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

  4. 【JZOJ3624】【SDOI2014】数数(count) AC自动机+数位dp

    题面 100 容易想到使用AC自动机来处理禁忌子串的问题: 然后在自动机上数位dp,具体是: \(f_{i,j,0/1}\)表示填了\(i\)位,当前在自动机的第\(j\)个结点上,\(0\)表示当前 ...

  5. uva11361 特殊数的数量(数位dp)

    题目传送门 题目大意:给你一个n-m的区间,问你这个闭区间内的特殊数有几个,特殊数的要求是 数的本身 和 各位数字之和  mod k 等于0. 思路:刚接触数位dp,看了网上的题解,说用dp[i][j ...

  6. 【ECNU77】位与数对个数(数位DP)

    点此看题面 大致题意: 求\(\sum_{x=0}^{a-1}\sum_{y=0}^{b-1}[(x\&y)<k]\). 数位\(DP\) 显然数位\(DP\)吧. 我们设\(f_{n, ...

  7. 【Dream Counting, 2006 Dec-数数的梦】数位dp

    题意:给定两个数,问区间[A,B]中0~9分别出现了多少次.A,B<=10^18 题解:应该是最裸的数位dp吧..一开始没有记忆化tle了TAT 我们可以求出区间[0,B]的,再减去区间[0,A ...

  8. bzoj1833: [ZJOI2010]count 数字计数&&USACO37 Cow Queueing 数数的梦(数位DP)

    难受啊,怎么又遇到我不会的题了(捂脸) 如题,这是一道数位DP,随便找了个博客居然就是我们大YZ的……果然nb,然后就是改改模版++注释就好的了,直接看注释吧,就是用1~B - 1~A-1而已,枚举全 ...

  9. P4317 花神的数论题 动态规划?数位DP

    思路:数位$DP$ 提交:5次(其实之前A过,但是调了调当初的程序.本次是2次AC的) 题解: 我们分别求出$sum(x)=i$,对于一个$i$,有几个$x$,然后我们就可以快速幂解决. 至于求个数用 ...

随机推荐

  1. UVa 11085 - Back to the 8-Queens

    题目:给你一个棋盘上的八个皇后.每行一个.如今让他们互相不攻击,每一个皇后仅仅能竖着移动, 一次能够移动到本列的不论什么位置,问最少移动几步.能满足要求. 分析:搜索,八皇后.由于八皇后仅仅有92组解 ...

  2. ZOJ Problem Set - 3229 Shoot the Bullet 【有上下界网络流+流量输出】

    题目:problemId=3442" target="_blank">ZOJ Problem Set - 3229 Shoot the Bullet 分类:有源有汇 ...

  3. mahout处理路透社语料步骤,转换成须要的格式

    首先下载路透社语料(百度就能够下载): 然后上传Linux 并解压到指定文件夹.Tips:此处我放在可 /usr/hadoop/mahout/reutersTest/reuters tar -zxvf ...

  4. js中arguments对象和this对象

    js中arguments对象和this属性 如果不注重复习,花时间准备的材料毫无意义 arguments对象和this对象都是对象 直接来代码 <!DOCTYPE html> <ht ...

  5. 异步Ajax

    Ajax异步刷新应用在Web开发中经常用到,在过去WebForm中通常是使用JQuery和一般处理程序或者aspx页面来实现: 在MVC中,虽然依然可以使用一般处理程序,但是一般还是通过在Contro ...

  6. Python(四) 分支、循环、条件与枚举

    一.什么是表达式 表达式(Expression)是运算符(operator)和操作数(operand)所构成的序列 二.表达式的优先级 三.表达式优先级练习 优先级同级 从左往右计算 1 or 2 a ...

  7. Git 操作笔记

    ¥先放个地址:这个视频超详细 https://www.bilibili.com/video/av10475153 分了2部分: 1是GitHub的功能介绍:2是pc端+doc命令的操作+发布个人网站 ...

  8. GPT模式下ghost系统 安装方法

    GPT模式下ghost系统 安装方法 1.UEFI进入PE 2.使用diskgenius 软件 分区,选择GPT方式分区 3.使用CGI ghost 系统 文件到安装盘 4.UEFI修复:软件为 BC ...

  9. UVALive 7146 Defeat The Enemy

    Defeat The Enemy Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Long long ...

  10. C# Socket服务端及多客户端连接通信实现

    服务端代码(控制台示例): static List<Socket> Sockets = new List<Socket>(); static void Main(string[ ...