【BZOJ3530】数数(AC自动机,动态规划)

题面

BZOJ

题解

很套路的\(AC\)自动机+\(DP\)

首先,如果长度小于\(N\)

就不存在任何限制

直接大力\(DP\)

然后强制限制不能走到带有标记的点上面

如果长度恰好为\(N\)的长度

那么,要考虑是否恰好卡在范围里面

于是\(DP\)状态多记一维

表示是否卡在范围里面

最后求一下和就行啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 2000
#define MOD 1000000007
struct Node
{
int vis[10];
int lt,fail;
}t[MAX];
int tot,m;
char N[MAX],ch[MAX];
int f[MAX][MAX][2],g[MAX][MAX];
void insert(char *s)
{
scanf("%s",s+1);
int l=strlen(s+1),now=0;
for(int i=1;i<=l;++i)
{
if(!t[now].vis[s[i]-48])
t[now].vis[s[i]-48]=++tot;
now=t[now].vis[s[i]-48];
}
t[now].lt=1;
}
void GetFail()
{
queue<int> Q;
for(int i=0;i<=9;++i)
if(t[0].vis[i])Q.push(t[0].vis[i]);
while(!Q.empty())
{
int u=Q.front();Q.pop();
t[u].lt|=t[t[u].fail].lt;
for(int i=0;i<=9;++i)
if(t[u].vis[i])
t[t[u].vis[i]].fail=t[t[u].fail].vis[i],Q.push(t[u].vis[i]);
else t[u].vis[i]=t[t[u].fail].vis[i];
}
}
int main()
{
scanf("%s",N+1);
scanf("%d",&m);
while(m--)insert(ch);
GetFail();
int l=strlen(N+1);
long long ans=0;
g[0][0]=1;
for(int i=0;i<l;++i)
for(int u=0;u<=tot;++u)
if(!t[u].lt)
{
for(int k=0;k<=9;++k)
if(!t[t[u].vis[k]].lt)
{
if(!i&&!k)continue;
(g[i+1][t[u].vis[k]]+=g[i][u])%=MOD;
}
}
for(int i=1;i<l;++i)
for(int j=0;j<=tot;++j)
ans=(ans+g[i][j])%MOD;
f[0][0][1]=1;
for(int i=0;i<l;++i)
for(int u=0;u<=tot;++u)
if(!t[u].lt)
{
for(int k=0;k<=9;++k)
if(!t[t[u].vis[k]].lt)
{
if(!i&&!k)continue;
(f[i+1][t[u].vis[k]][0]+=f[i][u][0])%=MOD;
if(k<N[i+1]-48)(f[i+1][t[u].vis[k]][0]+=f[i][u][1])%=MOD;
if(k==N[i+1]-48)(f[i+1][t[u].vis[k]][1]+=f[i][u][1])%=MOD;
}
}
for(int i=0;i<=tot;++i)
ans=(ans+f[l][i][0])%MOD,ans=(ans+f[l][i][1])%MOD;
printf("%lld\n",ans);
return 0;
}

【BZOJ3530】数数(AC自动机,动态规划)的更多相关文章

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

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

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

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

  3. [BZOJ 3530] [Sdoi2014] 数数 【AC自动机+DP】

    题目链接:BZOJ - 3530 题目分析 明显是 AC自动机+DP,外加数位统计. WZY 神犇出的良心省选题,然而去年我太弱..比现在还要弱得多.. 其实现在做这道题,我自己也没想出完整解法.. ...

  4. BZOJ1030 [JSOI2007]文本生成器 AC自动机 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1030 题意概括 给出n个模式串,问长度为m的串中有多少个至少含有这n个模式串中的任意一个. 注意, ...

  5. 【BZOJ1030】[JSOI2007]文本生成器 AC自动机+动态规划

    [BZOJ1030][JSOI2007]文本生成器 Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文 ...

  6. 【JSOI2007】文本生成器 题解(AC自动机+动态规划)

    题目链接 题目大意:给定$n$个子串,要求构造一个长度为$m$的母串使得至少有一个子串是其子串.问方案数. ------------------------ 我们可以对要求进行转化:求出不合法的方案数 ...

  7. UVA - 11468 (AC自动机+动态规划)

    建立AC自动机,把AC自动机当做一张图,在上面跑L个节点就行了. 参考了刘汝佳的代码,发现可能有一个潜在的Bug--如果模式串中出现了没有指定的字符,AC自动机可能会建立出错. 提供一组关于这个BUG ...

  8. 视频游戏的连击 [USACO12JAN](AC自动机+动态规划)

    传送门 默认大家都学过trie与AC自动机. 先求出fail,对于每个节点维护一个sum,sum[u]待表从根到u所形成的字符串能拿到几分.显然sum[u]=sum[fail] + (u是几个字符串的 ...

  9. BZOJ2553 Beijing2011禁忌(AC自动机+动态规划+矩阵快速幂+概率期望)

    考虑对一个串如何分割能取得最大值.那么这是一个经典的线段覆盖问题,显然每次取右端点尽量靠前的串.于是可以把串放在AC自动机上跑,找到一个合法串后就记录并跳到根. 然后考虑dp.设f[i][j]表示前i ...

随机推荐

  1. mongodb学习一

    Windows 平台安装 MongoDB MongoDB 下载 MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制 ...

  2. JDBCTemplate与模板设计方法(二)

    前言:上一篇博客介绍了模板方法模式,并且给出了一个小demo,简单对模板方法进行了实现,接下来我们把目光转向spring的源码JDBCTemplate,看一看spring是如何对jdbc进行高度封装的 ...

  3. 老男孩Python全栈开发(92天全)视频教程 自学笔记05

    day5课程内容: 集成开发环境(IDE) VIM #经典的Linux下的文本编辑器 Eclipse #Java IDE Visual Studio #微软开发的IDE notepad++ subli ...

  4. 02 浅析Spring的AOP(面向切面编程)

    1.关于AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.O ...

  5. 启动Activity的形式

    问:为什么service里面startActivity抛异常,activity不会? No1: 启动activity有两种形式: 1)直接调用Context类的startActivity方法:这种方式 ...

  6. 计蒜客 无脑博士 bfs

    题目链接无脑博士的试管们 思路:直接模拟倒水过程即可,但是需要记忆判断当前的情况是否已经处理过.dfs和bfs都ok AC代码 #include <cstdio> #include < ...

  7. XOR (莫队)

    Time Limit: 2000 ms   Memory Limit: 256 MB Description 给定一个含有n个整数的序列 a1, a2,..., an. 定义 f(x,x) = a[x ...

  8. git 命令和使用场景总结

    资料地址:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000    http://w ...

  9. home目录迁移至新分区

    在用户home目录越来越大时,就可以考虑将home目录迁移至新的分区. 1.创建新分区. fidisk /dev/sda:用磁盘管理器打开磁盘 n:新建 +10g :设置分区为10G w :保存 保存 ...

  10. R+openNLP︱openNLP的六大可实现功能及其在R语言中的应用

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- openNLP是NLP中比较好的开源工具,R语 ...