给出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指针遍历是为了统计出当前串包含的子串。

 

模板题:

【HDU】2222 Keywords Search

【HDU】2896 病毒侵袭

【HDU】3065 病毒侵袭持续中

【ZOJ】3430 Detect the Virus (用int存char)

【ZOJ】3228 Searching the String

 

矩阵:

把自动机上可行的路径构造出矩阵,对矩阵n次方后,mat[i][j]的值就是从i到j走n步的路径数。

【POJ】2778 DNA Sequence

【HDU】2243 考研路茫茫――单词情结

 

DP:

【POJ】1625 Censored!

题意:给出病毒串,求长度为n且不含病毒串的DNA种数。

dp[i][j]表示长度为i时,以自动机上结点编号为j结尾的种数。dp[i][j]+=dp[i-1][k],k是自动机上能转移到j的结点,且j、k都不是病毒串的结尾。(dp[0][0]=1)

 

 

【HDU】2825 Wireless Password

题意:给出字符串(<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)

 

【HDU】2457 DNA repair

题意:给出病毒串(<50),求最少的修改次数,使得DNA串不含病毒串。

dp[i][j]表示长度为i时,以自动机上结点编号为j结尾,使得该DNA串不含病毒串的最小修改次数。每次转移枚举是否需要修改,以及需要修改的字符。

 

【HDU】2296 Ring

题意:给出n个字符串,以及每个字符串的权值,求权值最大,字符串长度不超过m,最短且字典序最小的字符串。

dp[i][j]表示长度为i时,以自动机上结点编号为j结尾能构造的最大权值。dp[i][j]=max(dp[i-1][k]+cost[j])。

 

【HDU】3341 Lost's revenge

题意:给出n个DNA(n<50),以及一个字符串s,求s的一个排列,使其包含最多的DNA串。

对A,C,G,T哈希成一个状态,dp[i][j]表示状态为i,当前s的最后一个DNA为第j个所包含的DNA个数。

 

【HDU】3247 Resource Archiver

题意:有n(<10)个01串以及m(<1000)个病毒串,将01串拼接成最短的且不含病毒串。

将01串和病毒串一起构造自动机,枚举每个01串的结尾广搜,可以得到该串和其他01串结尾的最短距离。

对n个01串二进制压缩,dp[i][j]表示状态为i,最后拼接上的01串是第j个。

 

【ZOJ】3494 BCD Code

题意:给出n(<100)个长度(<20)的01病毒串,求A~B的BCD编码中,不含病毒串的个数。0 < AB < 10200

先预处理出自动机中每个结点,往0~9转移的后继结点。

数位DP,用DFS实现。

DFS(int rt,int pos,bool bound,bool zero)表示当前自动机的位置在rt,数字A或B枚举到第pos位,是否有边界限制,是否存在前导零。

posted on 2012-08-09 18:24  DrunBee  阅读(3410)  评论(0编辑  收藏  举报