昨天開始搞ac自動機,其實搞完kmp和trie樹之後搞ac自動機還是很簡單的,主要是形成一套ac自動機的**風格比較艱難,找了份簡潔明瞭實用性強的**分析了一天,以後就按這個風格寫了。
hdu2896
模板題,藉此把我加注釋的模板貼出來~
#include #include #include #include using namespace std;
int next[100001][128]; //trie樹
int fail[100001]; //失敗指標,相當於kmp的next陣列
int mark[100001]; //標記陣列,記錄節點資訊
bool used[501];
int ans;
int root,sum;
int n,m;
int newnode() //產生新的節點
void init() //初始化
void insert(char * s,int id) //構造trie樹
}while (!mq.empty())}}
/*這樣形成next構成乙個閉合的圖,對每個節點的所有孩子節點都能出發,要麼走到其真正孩子節點,要麼其沒有這個孩子,相當
於失配,走到失配後來到的位置,如果走到根節點還失配,則形成迴圈,看著是一條鏈,其實由於每次都是記錄的之前的資訊,記錄
之後尋找下乙個位置的花費是1,可以畫出這個bfs遞推過程體會一下
這樣形成的fail就是正常的fail指標了,即當前節點匹配下一節點失敗時要去的節點,由於這裡面跟next聯絡到一起,他們相互作用,使得
任意一次查詢的花費都是1,畫圖體會下一條鏈是怎樣形成的是最好的理解方式
*/}void query(char * s,int id)
for (int i=0;i<=len;i++)}}
}void dp()}}
}double ans=0;
//走到m步仍然沒有匹配成功的結果加起來便是不能匹配成功的概率,所有能匹配成功的結果
//都沒繼續遞推,所以走到m的時候沒有匹配成功便代表一直沒有匹配成功
for (int i=0;i>n>>m&&n+m)
scanf("%s",ch+1);
next[0]=next[1]=0;
getnext();
dp();
}}
ac自動機版:求出所有滿足題意的結果,相加#include #include #include #include using namespace std;
int next[1010][26];
int fail[1010];
int sum,root;
int n,m;
double dp[1010][15]; //當前步數為i,匹配的節點編號為j(其實根節點是0,其餘節點依次類推,自動機只有一條鏈,故也能理解為匹配長度)
double p[26];
char ch[15];
int newnode()
void init()
void insert(char * s)
}while (!mq.empty())}}
}int main()
init();
scanf("%s",ch);
insert(ch);
build();
int len=strlen(ch);
dp[0][0]=1; //第0步走到根節點的概率為1
for (int i=0;i
hdu2457
又是一道ac自動機加dp的題目,花了一晚上時間才寫出來,還是不熟悉用ac自動機完成樹形dp。。。
這道題讓求改變某些點使得不含病毒串的最少改變步數,那麼對目標串進行dp,對於目標串上的每個節點都有兩種選擇,要麼改變要麼不改變,然後,對每一步,列舉所有節點,從這個節點出發到其子節點作為待更新節點,看從這個節點出發能否使得下一步到待更新節點代表的狀態更優,如果待更新節點和當前步數匹配的節點相同,則表示不改變這個節點,不同則表示改變這個節點花費加1,然後看步數為len時在哪個狀態花費最小,輸出即可。
附**:
#include #include #include #include #include #include using namespace std;
int next[1010][4];
int fail[1010];
int mark[1010];
int sum,root;
map mp;
int n,m;
char ch[1010];
int dp[1010][1010]; //當前匹配的長度為i,處於t狀態,注意只需要匹配長度為len即匹配完成,由於值能變,所以在哪個位置不重要
const int inf=0x3f3f3f3f;
int newnode()
void init()
void insert(char * s)
}while (!mq.empty())}}
}int min(int a,int b)
void solve(char * s,int ca)
int main()
{ mp['a']=0;
mp['g']=1;
mp['c']=2;
mp['t']=3;
int ca=1;
while (cin>>n&&n)
{init();
for (int i=0;i
AC自動機 建立nlogn個AC自動機
string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...
AC自動機 學習筆記
是一種數學模型,大概就是由一堆狀態和狀態轉移規則等東西構成,能與外界交換資訊,並改變動作。這個是理論上的東西,了解就行,對ac自動機的理解沒有大影響。通俗的講就是在trie上做kmp,處理多模式串匹配問題。trie 的每個結點就是乙個狀態,根結點是初始狀態。ac自動機的行為被定義為一下3個函式 1....
AC自動機學習小記
ac自動機,aho corasick automaton,該演算法在1975年產生於貝爾實驗室,是著名的多模匹配演算法。其實ac自動機就是tire加上kmp。乙個簡單的問題 hdu2222 給出多個模式串,在給出乙個文字串,問模式串在文字串中出現了多少次。最簡單的做法就是將模式串加入的tire中,在...