首先是描述個大概。不說一些特殊的DP 或者借用矩陣來狀態轉移 (這些本質都是同樣的)。編碼
只講AC自動機和DP的關係(我的理解)。spa
AC自動機 又能夠叫作狀態機。壓縮
我一開始的認爲。AC 自動機提供了一些節點的信息。以及那些節點之間的關係。(節點也就是咱們建立的 Trie圖的節點。每每咱們會有一維這個信息)。
而後咱們作DP的時候。就好像是 「順着」 AC自動機指導給咱們的方向。而後作狀態轉移等等。這是一種感性的認識。
如今我認爲。AC自動機自己就是一個大狀態。同時父親和孩子的關係給了咱們DP轉移時候的方向。當咱們建立AC自動機的時候。就是在初始化初始狀態。
你能夠這樣想。一個AC自動機就是一張紙。咱們要發生狀態轉移的時候。就是拿另一張紙印在上面。而且添加一些東西。那爲什麼有所謂的感性的認識呢?咱們以前的感性的認識有沒有錯呢?答案固然是沒有的。由於咱們每每設置一開始全部的屬性都是INF (無效)。而且令。dp[0][0] = 0(只是舉個例子。)。同時碰到dp[i][j] = INF時候。咱們不發生轉移。致使了好像咱們從根節點開始更新慢慢延展出去。好像就是在一個AC自動機上面作延展。(固然不一樣的人有不一樣的見解。哪一種比較好想就用哪一個。)並且兩種思想都很重要。一種能夠更好理解編碼、一種可以更好地提供思路。
對於問題:不能出現非法串。
咱們的作法是不更新非法點。也不轉移非法點。(非法點。就是 root->該點的路徑是一個非法串)。
對於問題: 必須出現合法串
咱們的作法是增長一維用狀態壓縮。來肯定該串的出現。
同時有一題 是要肯定串的構成中必定有指定數量元素的。咱們是對元素進行了狀壓(該題多了個進制轉化).
對於問題: 最大積分串
咱們的作法就是普通的維護dp[i+1][ch[j][k]] = MAX(dp[i+1][ch[j][k]],dp[i][j]+val[ch[j][k]]).
對於問題:含有主串。
主串修改問題:主串具備指導意義。就好比若是你的
主串刪除問題: