记忆化搜索,设$f[i][j]$表示符号$i$一开始kmp指针为$j$,中间匹配了多少次,$g[i][j]$则表示匹配结束后kmp指针的位置。

时间复杂度$O(nl^2)$。

#include<cstdio>
#include<cstring>
const int N=26,M=105,P=10000;
int n,m,F,i,j,len[N],nxt[M],f[N][M],g[N][M],v[N][M];char s[M],a[N][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;
}

  

最新文章

  1. Linux服务器上监控网络带宽的18个常用命令
  2. [deviceone开发]-百度地图do_BaiduMap的示例
  3. Leetcode: Strong Password Checker
  4. C#中TreeView与数据库绑定
  5. java多线程编程(二创建线程)
  6. VS2010/MFC编程入门之四(MFC应用程序框架分析)
  7. codeblocks创建和使用静态库(C语言)
  8. [Angular 2] Passing data to components with @Input
  9. JDBC连接池-C池3P0连接
  10. ubuntu16.04下安装chrome
  11. 您的快递(高并发服务器之poll和epoll)请签收
  12. Golang学习教程
  13. mac 上运行httpserver的问题
  14. C# 运用反射把实体类反射成你所想要的格式
  15. 20165205 2017-2018-2 《Java程序设计》实验三 敏捷开发与XP实践
  16. php排序算法及二分法查找
  17. C++STL之Vector的应用
  18. CSS-文本垂直居中
  19. position属性详解
  20. (转)MySQL 线程池内幕

热门文章

  1. .net学习笔记---lambda表达式(自执行方法)
  2. 记录一个mysql按日期分组统计的查询
  3. JAVA基础学习之IP简述使用、反射、正则表达式操作、网络爬虫、可变参数、了解和入门注解的应用、使用Eclipse的Debug功能(7)
  4. Delphi面向对象---接口
  5. ExcelReport第一篇:使用ExcelReport导出Excel
  6. Task使用小结
  7. 基于类和基于函数的python多线程样例
  8. POJ2778 DNA Sequence(AC自动机 矩阵)
  9. PHP利用jquery生成各种验证码和Ajax验证
  10. 第十三篇:在SOUI中使用有窗口句柄的子窗口