给出n个单词,再给出一段包含m个字符的文章,找出有多少个单词在文章里出现过。
1、对n个单词构造字典树。
2、构造失败指针。
设当前节点为X,失败指针指向Y。
1。若当前节点X没有儿子t,则X的儿子t等价于Y的儿子t。
2。若当前节点X有儿子t,t的失败指针指向Y的儿子t。
Y与X有最长公共后缀。
3、模式匹配。
沿着next指针遍历。
例:4个单词:0101、1011、1100、0010。在构造完失败指针后,顺便完善next指针,使得匹配时只需沿着next指针遍历,匹配时沿着fail指针遍历是为了统计出当前串包含的子串。
模板题:
【ZOJ】3430 Detect the Virus (用int存char)
【ZOJ】3228 Searching the String
矩阵:
把自动机上可行的路径构造出矩阵,对矩阵n次方后,mat[i][j]的值就是从i到j走n步的路径数。
DP:
题意:给出病毒串,求长度为n且不含病毒串的DNA种数。
dp[i][j]表示长度为i时,以自动机上结点编号为j结尾的种数。dp[i][j]+=dp[i-1][k],k是自动机上能转移到j的结点,且j、k都不是病毒串的结尾。(dp[0][0]=1)
题意:给出字符串(<10),求至少由x个字符串组成的长度为n的字符串种数。
dp[i][j][k]表示长度为i时,以自动机上结点编号为j结尾,把用到的串二进制压缩为k的种数。dp[i][j][k]+=dp[i-1][p][t],p是自动机上能转移到j的结点。(dp[0][0][0]=1)
题意:给出病毒串(<50),求最少的修改次数,使得DNA串不含病毒串。
dp[i][j]表示长度为i时,以自动机上结点编号为j结尾,使得该DNA串不含病毒串的最小修改次数。每次转移枚举是否需要修改,以及需要修改的字符。
题意:给出n个字符串,以及每个字符串的权值,求权值最大,字符串长度不超过m,最短且字典序最小的字符串。
dp[i][j]表示长度为i时,以自动机上结点编号为j结尾,能构造的最大权值。dp[i][j]=max(dp[i-1][k]+cost[j])。
题意:给出n个DNA(n<50),以及一个字符串s,求s的一个排列,使其包含最多的DNA串。
对A,C,G,T哈希成一个状态,dp[i][j]表示状态为i,当前s的最后一个DNA为第j个所包含的DNA个数。
题意:有n(<10)个01串以及m(<1000)个病毒串,将01串拼接成最短的且不含病毒串。
将01串和病毒串一起构造自动机,枚举每个01串的结尾广搜,可以得到该串和其他01串结尾的最短距离。
对n个01串二进制压缩,dp[i][j]表示状态为i,最后拼接上的01串是第j个。
题意:给出n(<100)个长度(<20)的01病毒串,求A~B的BCD编码中,不含病毒串的个数。0 < A ≤ B < 10200。
先预处理出自动机中每个结点,往0~9转移的后继结点。
数位DP,用DFS实现。
DFS(int rt,int pos,bool bound,bool zero)表示当前自动机的位置在rt,数字A或B枚举到第pos位,是否有边界限制,是否存在前导零。