當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
BZOJ 1030: [JSOI2007]文本生成器 [AC自动机 DP]
生活随笔
收集整理的這篇文章主要介紹了
BZOJ 1030: [JSOI2007]文本生成器 [AC自动机 DP]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1030: [JSOI2007]文本生成器
Time Limit:?1 Sec??Memory Limit:?162 MBSubmit:?3953??Solved:?1614
[Submit][Status][Discuss]
Description
JSOI交給隊員ZYX一個任務,編制一個稱之為“文本生成器”的電腦軟件:該軟件的使用者是一些低幼人群,
他們現在使用的是GW文本生成器v6版。該軟件可以隨機生成一些文章―――總是生成一篇長度固定且完全隨機的文
章—— 也就是說,生成的文章中每個字節都是完全隨機的。如果一篇文章中至少包含使用者們了解的一個單詞,
那么我們說這篇文章是可讀的(我們稱文章a包含單詞b,當且僅當單詞b是文章a的子串)。但是,即使按照這樣的
標準,使用者現在使用的GW文本生成器v6版所生成的文章也是幾乎完全不可讀的?。ZYX需要指出GW文本生成器 v6
生成的所有文本中可讀文本的數量,以便能夠成功獲得v7更新版。你能幫助他嗎?
Input
輸入文件的第一行包含兩個正整數,分別是使用者了解的單詞總數N (<= 60),GW文本生成器 v6生成的文本固
定長度M;以下N行,每一行包含一個使用者了解的單詞。這里所有單詞及文本的長度不會超過100,并且只可能包
含英文大寫字母A..Z
Output
一個整數,表示可能的文章總數。只需要知道結果模10007的值。
Sample Input
2 2A
B
Sample Output
100題意:求長度為m且含有至少一個模板串的字符串個數
好神啊 含有至少一個不好求,那就求不含模板串的然后總數減 計數問題組合數學做不了就考慮DP f[i][j]表示長度為i匹配到自動機上節點j的不含模板串的方案數 轉移 f[i][j]-->f[i+1][t[j].ch[k]] 如何判斷一個串不含模板串?首先f[i][j]已經保證1..i-1是不含模板串的啦,只要保證第i個字符加入后也不含就行了 ins時模板串終點打標記,本身且Fail祖先沒有標記就說明AC自動機上j結尾的沒有模板串 但是有的字符模板串里沒有啊?給root把孩子補全就行了【實際上不補全也是可以的,反正默認走到了根,最后f[m][根]也統計】 思路和KMP一樣,都是一邊生成字符串一邊在KMP/AC自動機上匹配, #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=105,M=6005,MOD=10007; int n,m; char s[N]; struct node{int ch[26],fail,val; }t[M]; int sz; void ins(char s[]){int u=0,n=strlen(s+1);for(int i=1;i<=n;i++){int c=s[i]-'A';if(!t[u].ch[c]) t[u].ch[c]=++sz;u=t[u].ch[c];}t[u].val=1; } int q[M],head,tail; void getAC(){head=tail=1;for(int i=0;i<26;i++){if(!t[0].ch[i]) t[0].ch[i]=++sz;q[tail++]=t[0].ch[i];}while(head!=tail){int u=q[head++];t[u].val|=t[t[u].fail].val;for(int i=0;i<26;i++){int &v=t[u].ch[i];if(!v) {v=t[t[u].fail].ch[i];continue;}t[v].fail=t[t[u].fail].ch[i];q[tail++]=v;}} } int f[N][M],ans; void dp(){f[0][0]=1;for(int i=1;i<=m;i++){for(int j=0;j<=sz;j++) if(!t[j].val&&f[i-1][j]!=0)for(int k=0;k<26;k++) if(!t[t[j].ch[k]].val)f[i][t[j].ch[k]]=(f[i][t[j].ch[k]]+f[i-1][j])%MOD;}for(int j=0;j<=sz;j++) ans=(ans+f[m][j])%MOD; } int main(){//freopen("in.txt","r",stdin);scanf("%d%d",&n,&m);//printf("hi %d %d nm\n",n,m);for(int i=1;i<=n;i++) scanf("%s",s+1),ins(s);getAC();dp();int tmp=1;for(int i=1;i<=m;i++) tmp=(tmp*26)%MOD;printf("%d",(tmp-ans+MOD)%MOD); }
?
總結
以上是生活随笔為你收集整理的BZOJ 1030: [JSOI2007]文本生成器 [AC自动机 DP]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: arp的***和防御
- 下一篇: angular2、ng2 http ge