BZOJ2061 : Country
记忆化搜索,设f[i][j]表示符号i一开始kmp指针为j,中间匹配了多少次,g[i][j]则表示匹配结束后kmp指针的位置。
时间复杂度O(nl2)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #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; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步