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#include#include#includeusing namespacestd;#define inf (1<<25)關於zoj3190:#define max(x,y) ((x)<(y)?(y):(x))
structnode
};node node[1005];
booldp[2][1005][1<<10];map<
char
,int
>id;queue<
int>q;
intw[15],cnt,n,l;
voidinit()memset(dp,false,
sizeof
(dp));memset(w,0,
sizeof
(w));cnt=0;dp[0][0][0]=true;
}voidaddword(
char
*ch,
intnum)u=node[u].next[v];
}node[u].sta|=(1<<num);
}voidsetfail()}}
}intget(
intsta)
returnsum;
}int
main
()setfail();
for(
inti=1;i<=l;++i)}}
}}ans=-inf;
for(
inti=0;i<=cnt;++i)
}if(ans<0)printf("no rabbit after 2012!\n");
elseprintf("%d\n",ans);
}return0;
}
#include#include#includeusing namespace std;
#define inf (1<<30)
#define min(x,y) ((x)<(y)?(x):(y))
struct node
};node node[60005];
queueq;
queue>qq;
int cnt,sum,dp[55][1026],dis[55][55],hash[55],use[55],used[60005];
void addword(char *ch,int num)
now=node[now].next[u];
}if(num==-1) node[now].flag=true;
else node[now].sta|=num;
}void setfail()
}q.push(u);}}
}}int main()}}
}memset(dp,-1,sizeof(dp));
qq.push(make_pair(0,0));dp[0][0]=0;
while(!qq.empty())}}
ans=inf;goal=(1<
暖 墟 AC自動機 AC自動機的總結與運用
kmp 匹配單串,線性掃瞄,在失配時用next陣列引導j指標回溯,進行下一步匹配。trie樹 多模式的匹配,構造26叉樹,同時記錄多個串的情況,記錄結尾,進行匹配。kmp trie樹 ac自動機 ac自動機 給乙個字典,再給乙個文字,問這個文字裡出現了字典裡的哪些字。可以用n個單詞的n次kmp演算法...
AC自動機總結
講解 ac自動機講解1 ac自動機講解2 1.模版題 hdu2222 include include include using namespace std int k int n char s 10010 60 char mat 1100000 int cnt struct node trie 1...
AC自動機總結
考慮kmp問題的公升級版,即有多個模式串,單個文字串。問匹配次數。考慮對於每乙個模式串建乙個 fail 然後對於每乙個模式串都和文字串暴力跑。前置知識 trie樹,bfs 沒什麼好說的。演算法實現 我們考慮將所有的模式串放到一顆 trie 樹,如果匹配失敗的話轉移到 fail 指標上面去,這樣子複雜...