题目链接:

洛谷

LOJ

BZOJ

题目大意:给定 $n$ 个只含大写字母的串(称为可读串),问有多少种只含大写字母的长为 $m$ 的串,包含至少一个可读串。

$1\le n\le 60,1\le \text{每个串长}\le 100,1\le m\le 100$。


stmN年没发过博客了赶紧发一发

第一道在AC自动机上DP的题,纪念纪念。

首先可以发现答案就是所有串的个数减去不包含可读串的串的个数。

前半部分是 $26^m$。后半部分使用DP求解。

首先建出可读串的AC自动机。

令 $dp[i][j]$ 表示串长为 $i$,在AC自动机上走到编号为 $j$ 的节点的合法串个数。

如果走到 $j$ 的儿子 $k$ 这个节点的串合法,那么就可以从 $(i,j)$ 转移到 $(i+1,ch[j][k])$。

$dp[i+1][ch[j][k]]+=dp[i][j](0\le k<26)$

初始状态 $dp[0][0]=1$。答案为所有 $dp[m][i]$ 的最大值。

可能看到这里,你最大的疑问就是:如何判断走到点 $j$ 的串是否合法?真的可行吗?

想一想在AC自动机的fail的性质。我们就可以发现:如果从点 $j$ 不停沿fail往上跳,经过的所有点(包括 $j$)没有串尾的节点,那么 $j$ 合法,否则不合法。

这个合法性可以在BFS求fail时顺带求出。

(仔细想一想在AC自动机上跑匹配的本质就明白了)

时间复杂度 $O(m\sum|S|)$,空间复杂度 $O(\sum|S|)$,全都带一个 $26$ 的常数。

代码:

#include<bits/stdc++.h>
using namespace std;
const int mod=;
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
char ch=getchar();int x=,f=;
while(ch<'' || ch>'') f|=ch=='-',ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return f?-x:x;
}
int n,m,cnt,q[],h,r,ch[][],dp[][],fail[];
bool war[]; //war表示节点是否不合法(不合法!不合法!)
char str[];
void insert(char str[],int len){
int now=;
FOR(i,,len){
int p=str[i]-'A';
if(!ch[now][p]) ch[now][p]=++cnt;
now=ch[now][p];
}
war[now]=true; //串尾不合法
}
void build(){
h=;r=;
FOR(i,,) if(ch[][i]) q[++r]=ch[][i];
while(h<=r){
int u=q[h++];
FOR(i,,) if(ch[u][i]){
fail[ch[u][i]]=ch[fail[u]][i];
war[ch[u][i]]|=war[fail[ch[u][i]]];
//如果fail不合法,自己也不合法
q[++r]=ch[u][i];
}
else ch[u][i]=ch[fail[u]][i];
}
}
int qpow(int a,int b){
int ans=;
for(;b;b>>=,a=a*a%mod) if(b&) ans=ans*a%mod;
return ans;
}
int main(){
n=read();m=read();
FOR(i,,n) scanf("%s",str+),insert(str,strlen(str+));
build();
dp[][]=;
FOR(i,,m-) FOR(j,,cnt) FOR(k,,)
if(!war[ch[j][k]]) dp[i+][ch[j][k]]=(dp[i+][ch[j][k]]+dp[i][j])%mod;
//ch[j][k]合法,可以转移
int ans=qpow(,m);
FOR(i,,cnt) ans=(ans-dp[m][i]+mod)%mod; //容斥一下
printf("%d\n",ans); //答案
} AC自动机上DP

AC自动机上DP

[JSOI2007]文本生成器(AC自动机,DP)的更多相关文章

  1. [JSOI2007]文本生成器 --- AC自动机 + DP

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

  2. BZOJ 1030: [JSOI2007]文本生成器 [AC自动机 DP]

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3953  Solved: 1614[Submit][Stat ...

  3. 【bzoj1030】[JSOI2007]文本生成器 AC自动机+dp

    题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...

  4. 洛谷P4052 [JSOI2007]文本生成器 AC自动机+dp

    正解:AC自动机+dp 解题报告: 传送门! 感觉AC自动机套dp的题还挺套路的,,, 一般就先跑遍AC自动机,然后就用dp dp的状态一般都是f[i][j]:有i个字符,是ac自动机上的第j个节点, ...

  5. [BZOJ1030] [JSOI2007] 文本生成器 (AC自动机 & dp)

    Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  6. [BZOJ1030]:[JSOI2007]文本生成器(AC自动机+DP)

    题目传送门 题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是 ...

  7. BZOJ1030[JSOI2007]文本生成器——AC自动机+DP

    题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...

  8. 1030: [JSOI2007]文本生成器 ac自动机+dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=1030 求长度为m不包含n个子串的种数, 跑完ac自动机之后没办法跑矩阵快速幂,因为状态数比较大(6 ...

  9. [Bzoj1030][JSOI2007]文本生成器(AC自动机&dp)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1030 最最最常见的多串匹配问题!题目求至少包含一个子串的方案数,则可以转化成全部方案-不 ...

  10. BZOJ_1030_[JSOI2007]文本生成器_AC自动机+DP

    BZOJ_1030_[JSOI2007]文本生成器_AC自动机+DP Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群, 他 ...

随机推荐

  1. 如何使用jstack分析线程状态

    背景 记得前段时间,同事说他们测试环境的服务器cpu使用率一直处于100%,本地又没有什么接口调用,为什么会这样?cpu使用率居高不下,自然是有某些线程一直占用着cpu资源,那又如何查看占用cpu较高 ...

  2. 20155207 《网络对抗技术》EXP3 免杀原理与实践

    20155207 <网络对抗技术>EXP3 免杀原理与实践 基础问题回答 杀软是如何检测出恶意代码的? - 根据特征码进行检测(静态) - 启发式(模糊特征点.行为 ) - 根据行为进行检 ...

  3. WPF控件加阴影模糊问题

    原文:WPF控件加阴影模糊问题 不能直接把阴影加在控件上 应该加在控件的同级兄弟节点上,覆盖在底下就不会模糊了

  4. springmvc 结合 自动封装异常信息输出为json 报错 500内部服务器错误的原因

    补充:还有一个原因是因为spring的对象没有被成功注入,例如 mapper没有被成功注入,抛出异常时在这种封装场景下将会抛出 500 服务器内部错误, 这种情况下要排查还是靠debug然后看看到底是 ...

  5. ESLint 规则详解(二)

    接上篇 ESLint 规则详解(一) 前端界大神 Nicholas C. Zakas 在 2013 年开发的 ESLint,极大地方便了大家对 Javascript 代码进行代码规范检查.这个工具包含 ...

  6. Zip伪加密 破解ZIP密码

    ZIP是一种相当简单的分别压缩每个文件的存档格式.分别压缩文件允许不必读取另外的数据而检索独立的文件:理论上,这种格式允许对不同的文件使用不同的算法.不管用何种方法,对这种格式的一个告诫是对于包含很多 ...

  7. PHP学习 Cookie和Session

    <?phpheader("Content-type:text/html;charset=utf-8");session_start(); $_SESSION['count'] ...

  8. webpack简单原理及用法

    前言 如果你已经对Webpack精通了或者至少一直在工作中使用它,请关闭当前浏览器标签,无视这篇文章. 这篇文章本意是写给我自己看的,作为一篇Cookbook供快速查询和上手用.原因是虽然工作中会涉及 ...

  9. Linux第三周学习总结——构造一个简单的Linux系统MenuOS

    第三周学习总结--构造一个简单的Linux系统MenuOS 作者:刘浩晨 [原创作品转载请注明出处] <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...

  10. 2017-2018 第一学期201623班《程序设计与数据结构》-第9&10周作业问题总结

    一.作业内容 第8周作业 http://www.cnblogs.com/rocedu/p/7484252.html#WEEK08 第9周作业 http://www.cnblogs.com/rocedu ...