給出\(n\)個單詞和文字長度\(m\),求有多少文字滿足其內至少包含乙個單詞,答案對\(10007\)取餘。
直接求滿足的文字比較困難,我們考慮求答案的補集,也就是不包含任何乙個單詞的文字串的數量。對於這個答案我可以用\(dp\)求解,但考慮對單詞的查詢我們需要用\(a\)c自動機解,因此題目就比較明顯了,\(ac\)自動機上跑\(dp\),我們用\(dp[i][j]\)表示文字長度為\(i\),文字的最後乙個字元位於\(trie\)圖上的節點編號為\(j\)時的方案數。所以轉移方程就比較簡單了,\(dp[i+1][u]+=dp[i][v]\)(\(u\)能從\(v\)轉移過來),而這個方程的求法與區間\(dp\)類似,我們第一重列舉長度,因為每乙個解必定由更短的長度轉移過來。
不過有點必須闡明,我們雖然在\(dp\)方程中有一維列舉的是\(trie\)圖上的節點編號,實際還是每乙個字母,但有乙個類似匹配的過程,因此這個\(dp\)方程是正確的,它必定不會包含重複的狀態,也就可以求出正確答案。
#includeusing namespace std;
const int mod=10007;
int ch[6100][26],tot=1;
bool ed[6100];
void insert(char *s)
return res;
}int nxt[6100];
void getfail()}}
for(int i=1;i<=tot;i++)
}int dp[110][6010];
char s[110];
int main()
getfail();
dp[0][1]=1;
for(int i=0;ifor(int j=1;j<=tot;j++)
for(int k=0;k<26;k++)
if(!ed[j]&&!ed[ch[j][k]])dp[i+1][ch[j][k]]=(dp[i+1][ch[j][k]]+dp[i][j])%mod;//列舉的兩個點必定不是單詞結尾
int ans=qpow(26,m);
// for(int i=1;i<=tot;i++)
// cout
ans=(ans-dp[m][i]+mod)%mod;
printf("%d",ans);
}
bzoj 1030 文字生成器
題意 給出乙個n個單詞的字典,單詞長度 100 求長度為m的隨機字串中有多少個串至少包括乙個單詞 n 60,m 100 題解 好久沒有寫ac自動機啦,如今還記得模板真是難得 然而這似乎是trie圖?總之寫出來不差幾句話 首先至少包括乙個單詞這個條件不太好弄 那就轉化一下,求不含單詞的字串個數 然後就...
BZOJ 1030 文字生成器
1030 jsoi2007 文字生成器 time limit 1 sec memory limit 162 mb submit 4777 solved 1986 submit status discuss description jsoi交給隊員zyx乙個任務,編制乙個稱之為 文字生成器 的電腦軟體...
2017 8 14 文字生成器 失敗總結
以後凡是在乙個中出現 1次的題就直接轉0次用容斥好了 然後剩下的就是怎麼找乙個單詞也不出現的文字的個數了 顯然,這種計數類問題需要用dp 而且我們需要知道所有單詞會為我們新增字母造成影響,所以需要用ac自動機,跳過所有標記的單詞 以前是寫的指標ac自動機,但它不好寫而且巨慢 所以換了陣列 要注意用0...