关于AC自动机与DP的总结

本文总结了AC自动机的概念及其在状态压缩中的应用,详细阐述了如何设置状态要素,包括主串位置、自动机状态和模式串信息。同时探讨了在动态规划问题中如何利用AC自动机优化,如静态开点、状态压缩和最短路优化,通过具体题目ZOJ3545和ZOJ3190进行实例分析。
摘要由CSDN通过智能技术生成

AC自动机实际上是将字符串集合与状态一一对应,也算是一种状态压缩的手段。

对于状态,一般考虑这么几个要素:

1.考虑到了主串的第几位,这个一般就是状态的要素之一(其中一维),空间不够时可以考虑滚动数组(i&1)

2.自动机上的状态。这里注意自动机上的某点可能对应多个字符串的最后一位,因此在设置失败指针时,如有需要,可以记录下各个节点分别是哪些字符串的最后一位(可以用链表,也可以按位压缩为int)。转移的时候只考虑next数组的指向(注意这里可以做一个优化,若字典树中某节点不存在next子节点,可令其next子节点直接为失败指针,这样就构成了Trie图)。

3.关于模式串。这个一般见于关于字符串构造的DP。可以记录数目,也可以按位压缩记录哪些串被包含。见题:ZOJ3545 Rescue the Rabbit

关于状态的设定,可以按着一种思维方式去考虑:从某位往后,需要知道哪些状态才能不考虑前面的情况?或者说之前的那些要素可以影响后面?

另外关于AC自动机,可以考虑静态开点(事实上要建Trie图必须静态开点)。具体见代码(AC自动机静态设置,结合以上三种状态的DP)

4.AC自动机是以Trie图的形式展现,每个点表示AC自动机上的状态。那么当DP时如果自动机上无意义的状态过多,可以考虑加入BFS最短路进行优化,只考虑有意义的点,这是对DP时间空间进行压缩的一种方法。见题:ZOJ3190。令dp[i][j]表示自动机上状态为i,构造出的串包含目标串的情况为j时的最小长度。由于当i不为目标串后缀时,j的值不会改变,也就是说答案必定来自i为自动机上i目标串后缀的情况,这种情况最多55种,复杂度就大大减小。DP之前求解出各个有意义状态之间不经过病毒串条件下的最短路长度。在此基础上进行DP即可。(DP+最短路优化来压缩状态点)。

关于ZOJ3545

代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
#define INF (1<<25)
#define max(x,y) ((x)<(y)?(y):(x))
struct Node{
   
    int next[4],fail,sta;
    Node(){
   
        for(int i=0;i<4;++i) next[i]=0;fail=0;sta=0;
    }
};
Node node[1005];
bool dp[2][1005][1<<10];
map<char,int> ID;
queue<int> q;
int w[15],cnt,n,l;
void init(){
   
    for(int i=0;i<=cnt;++i){
   
        for(int j=0;j<4;++j) node[i].next[j]=0;
        node
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值