题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2825
解题思路:
给出n个串,询问至少包含其中k个串的长度为L的串的种类
AC自动机的作用就是为了枚举当前节点的所有自节点时找到最优的位置使得尽快到达单词结尾,以及到达某一节点时获得自己以及所有后缀链接的所有到达的单词末尾的所有情况(构造时直接处理)
状压DP:
用k表示状态。
eg. k=1023,在二进制下=1111111111,表示有1~10这10种不同的串
定义:dp[i][j][k],从根节点出发,长度为i,第i个字符停在j节点上,且拥有k对应的串种类的方法数
初始状态:dp[0][0][0] = 1
状态转移:dp[i][j][k] = (所有dp[i-1][ ][ ]中可以转移到当前状态的),但是枚举当前状态所有先前状态不好写,所以我们枚举所有当前状况累加到当前状态所有能到达的下一步状态即可。
u表示当前节点,用v表示当前节点某个能到的下一节点,val[v]表示v节点的“k值”
dp[i+1][v][ k|val[v] ] += dp[i][u][k];
一个需要想清楚的东西:当前这个状态能不能被枚举?
能被枚举意味着一定能到达这个点,(否则用它来给他的子节点计数就是错误的因为目前长度到不了)即到达这个点方法数至少为1,即dp[i][u][k]>0。
(否则应该需要根据当前的深度,枚举字典树所有深度<=当前深度的点,那样很麻烦)
代码:
#include
#include
#include
#include
#include
#include
总结:做AC自动机的题目做自闭了,我根本不会DP和矩阵。。。awsl