BZOJ2061 : Country
2016-02-19 20:43
302 查看
记忆化搜索,设$f[i][j]$表示符号$i$一开始kmp指针为$j$,中间匹配了多少次,$g[i][j]$则表示匹配结束后kmp指针的位置。
时间复杂度$O(nl^2)$。
时间复杂度$O(nl^2)$。
#include<cstdio> #include<cstring> const int N=26,M=105,P=10000; int n,m,F,i,j,len ,nxt[M],f [M],g [M],v [M];char s[M],a [M]; inline void up(int&x,int y){x+=y;if(x>=P)x-=P;} void dp(int x,int y){ if(v[x][y])return; int i,j; for(i=0,j=y;i<len[x];i++)if(a[x][i]>='a'){ while(j&&s[j+1]!=a[x][i])j=nxt[j]; if(s[j+1]==a[x][i])j++; if(j==m)up(f[x][y],1),j=nxt[j]; }else{ int k=a[x][i]-'A'; dp(k,j),up(f[x][y],f[k][j]),j=g[k][j]; } v[x][y]=1,g[x][y]=j; } int main(){ scanf("%d%s",&n,s),F=s[0]-'A'; while(n--){ scanf("%s",s),m=strlen(s); len[i=s[0]-'A']=m-2; for(j=2;j<m;j++)a[i][j-2]=s[j]; } scanf("%s",s+1),m=strlen(s+1); for(i=2;i<=m;nxt[i++]=j){ while(j&&s[j+1]!=s[i])j=nxt[j]; if(s[j+1]==s[i])j++; } dp(F,0); return printf("%d",f[F][0]),0; }
相关文章推荐
- 算法精讲学习笔记 排序(一)
- 【CODEVS1281】Xn数列
- UVA-10163 Storage Keepers (0-1背包)
- 绝对原创,Cheapest PBR Shader EVER!!!!
- 更新CocoaPods出现了错误
- css布局——百度前端技术学院
- js 实现长按效果(类似安卓的)
- 初探12306售票算法(二)-java代码实践
- js 实现长按效果(类似安卓的)
- java文件操作+流的使用
- codeforces 630D Hexagons!
- Mac安装MySQL初始密码设置
- maven项目tomcat编译后没有class文件
- HTML5离线存储原理及实现
- mysql阅读笔记二
- 6.10 Android 推送 极光推送
- java:堆栈,队列,枚举,链表
- Collections类
- String 截串
- 神经网络的学习 机器学习基础(4)