BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1009
字符串全部由0~9組成,給出一個(gè)串s,求一個(gè)長(zhǎng)度為n的串,不包含s的種類有多少.
?
分析
第一眼以為是組合.然后更滑稽的是用錯(cuò)誤的方法手算樣例居然算出來(lái)是對(duì)的...我數(shù)學(xué)是有多差...
題解也是看了好半天,有點(diǎn)難理解.
感覺(jué)PoPoQQQ神犇講得還是比較清楚的.傳送門(mén):http://blog.csdn.net/popoqqq/article/details/40188173
我們用dp[i][j]表示 : 長(zhǎng)度為i的串, 其長(zhǎng)度為j的后綴 與 s長(zhǎng)度為j的前綴 完全匹配的種類數(shù).
這樣的話最后的答案就是ans=sigma{dp[n][i]}(0<=i<m).
這里還有一個(gè)二維的a數(shù)組,就這個(gè)比較難解釋...
dp[i][y]可以由dp[i-1][x]轉(zhuǎn)移而來(lái),那么匹配的s的前綴由長(zhǎng)度x變成了長(zhǎng)度y,a[x][y]表示的就是在結(jié)尾添加一個(gè)字符后,匹配長(zhǎng)度從x變成y,這樣的字符有多少種.
那么 dp[i][y]=sigma{dp[i-1][x]*a[x][y]}.
這個(gè)可以用矩陣乘法算.
那么a數(shù)組怎么求呢?用kmp.
a[x][y]表示的是前綴匹配長(zhǎng)度由x變成了y的種類數(shù),那么從每一位i開(kāi)始匹配,如果匹配到了j,那么a[i][j+1]++(數(shù)組從0開(kāi)始,第i位之前匹配了i個(gè),匹配到第j位,應(yīng)該是j+1個(gè)).
?
p.s.我好菜呀...
?
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=100+5; 5 int n,m,p,ans; 6 char str[maxn]; 7 int f[maxn]; 8 9 struct matrix{ 10 int x[25][25]; 11 matrix(){ memset(x,0,sizeof x); } 12 int * operator [] (int id){ return x[id]; } 13 }dp,a; 14 void operator *= (matrix &x,matrix &y){ 15 matrix z; 16 for(int i=0;i<m;i++)for(int j=0;j<m;j++)for(int k=0;k<m;k++) 17 z[i][j]+=x[i][k]*y[k][j], z[i][j]%=p; 18 x=z; 19 } 20 void kmp(){ 21 for(int i=1;i<m;i++){ 22 int j=f[i]; 23 while(j&&str[i]!=str[j]) j=f[j]; 24 f[i+1]=str[i]==str[j]?j+1:0; 25 } 26 for(int i=0;i<m;i++)for(char k='0';k<='9';k++){ 27 int j=i; 28 while(j&&k!=str[j]) j=f[j]; 29 if(k==str[j]) a[i][j+1]++; 30 else a[i][0]++; 31 } 32 } 33 void quick_power(int y){ 34 for(;y;a*=a,y>>=1) if(y&1) dp*=a; 35 } 36 int main(){ 37 scanf("%d%d%d",&n,&m,&p); 38 scanf("%s",str); 39 kmp(); 40 dp[0][0]=1; 41 quick_power(n); 42 for(int i=0;i<m;i++) ans+=dp[0][i], ans%=p; 43 printf("%d\n",ans); 44 return 0; 45 } View Code?
1009: [HNOI2008]GT考試
Time Limit: 1 Sec??Memory Limit: 162 MBSubmit: 2815??Solved: 1738
[Submit][Status][Discuss]
Description
阿申準(zhǔn)備報(bào)名參加GT考試,準(zhǔn)考證號(hào)為N位數(shù)X1X2....Xn(0<=Xi<=9),他不希望準(zhǔn)考證號(hào)上出現(xiàn)不吉利的數(shù)字。
他的不吉利數(shù)學(xué)A1A2...Am(0<=Ai<=9)有M位,不出現(xiàn)是指X1X2...Xn中沒(méi)有恰好一段等于A1A2...Am. A1和X1可以為
0
Input
第一行輸入N,M,K.接下來(lái)一行輸入M位的數(shù)。 N<=10^9,M<=20,K<=1000
Output
阿申想知道不出現(xiàn)不吉利數(shù)字的號(hào)碼有多少種,輸出模K取余的結(jié)果.
Sample Input
4 3 100111
Sample Output
81HINT
Source
轉(zhuǎn)載于:https://www.cnblogs.com/Sunnie69/p/5554726.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 记录一下Android 长截屏功能
- 下一篇: C语言常见编程题及答案40题