Bzoj1009 [HNOI2008]GT考试
2016-07-17 11:22
302 查看
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 2872 Solved: 1769
Description
阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。
他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为
0
Input
第一行输入N,M,K.接下来一行输入M位的数。 N<=10^9,M<=20,K<=1000
Output
阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.
Sample Input
4 3 100111
Sample Output
81HINT
Source
动归。
用f[i][j]表示填到第i位,不吉利串匹配到第j位的方案数,动态规划。
kmp预处理出不吉利串的next数组,这样就可以利用next,在填每一位数时进行状态转移(如果填的下一个数能匹配,则匹配长度++,否则跳到next)
之后用矩阵乘法计算总方案数
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int n,m,k; int next[500]; char ch[30]; int a[30][30],b[30][30]; void getnext(char s[]){ next[0]=next[1]=0; int i,j; for(i=2,j=0;i<=m;i++){ while(j && s[j+1]!=s[i])j=next[j]; if(s[j+1]==s[i])j++; next[i]=j; } return; } void multi(int a[30][30],int b[30][30],int ans[30][30],int mod){ int tmp[30][30]; int i,j,k; for(i=0;i<m;i++) for(j=0;j<m;j++){ tmp[i][j]=0; for(k=0;k<m;k++) tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j])%mod; } for(i=0;i<m;i++) for(j=0;j<m;j++) ans[i][j]=tmp[i][j]; } int main(){ scanf("%d%d%d",&n,&m,&k); scanf("%s",ch+1); getnext(ch); int i,j; // for(i=0;i<m;i++) for(j=0;j<=9;j++){ int t=i; while(t && ch[t+1]-'0'!=j) t=next[t]; if(ch[t+1]-'0'==j)t++; if(t!=m)b[t][i]=(b[t][i]+1)%k;//转移 } // for(i=0;i<m;i++)a[i][i]=1; while(n){ if(n&1)multi(a,b,a,k); multi(b,b,b,k); n>>=1; } int sum=0; for(i=0;i<m;i++)sum=(sum+a[i][0])%k;//累计 printf("%d\n",sum); return 0; }
相关文章推荐
- PCA
- Nancy之实现API的功能
- 15.python笔记之psutil模块
- HDU 1196
- 前端资讯与资源
- html框架的使用
- is_int出现的问题
- php文件创建相关操作
- [2]一切都是对象
- 1小时教你突破写作瓶颈,成为文案高手
- array DEMO
- [c#基础]AutoResetEvent
- JavaEE中表现层、持久层、业务层的职责分析(转载)
- PHP页面跳转几种实现技巧
- 小白张的博客开篇
- javascript字符串和数组转换
- Android 所有权限大全
- isKindOfClass和isMemberOfClass的区别
- 自定义ToolBar
- Android动画学习之LayoutAnimation三