[LA 3942] Remember the Word
Posted newera
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LA 3942] Remember the Word相关的知识,希望对你有一定的参考价值。
Link:
Solution:
感觉自己字符串不太行啊,要加练一些蓝书上的水题了……
$Trie$+$dp$
转移方程:$dp[i]=sum{ dp[i+len(x)+1]} (x为从第i位开始的字符串的前缀)$
计算一个字符串前缀的多模式匹配在$Trie$树上跑一遍就行啦!
Code:
#include <bits/stdc++.h> using namespace std; const int MAXN=4e5+10,MOD=20071027; bool vis[MAXN]; char s[MAXN],tmp[MAXN]; int T,n,ch[MAXN][30],dp[MAXN],l,len,cnt=0,rt=0; int main() { while(~scanf("%s",s+1)) { memset(ch,0,sizeof(ch));memset(dp,0,sizeof(dp)); memset(vis,false,sizeof(vis)); T++;len=strlen(s+1); scanf("%d",&n);cnt=0; for(int i=1;i<=n;i++) { scanf("%s",tmp+1);l=strlen(tmp+1); int cur=rt; for(int j=1;j<=l;j++) { if(!ch[cur][tmp[j]-‘a‘]) ch[cur][tmp[j]-‘a‘]=++cnt; cur=ch[cur][tmp[j]-‘a‘]; } vis[cur]=true; } dp[len+1]=1; for(int i=len;i>=1;i--) { int cur=rt; for(int j=i;j<=len;j++) { if(!ch[cur][s[j]-‘a‘]) break; cur=ch[cur][s[j]-‘a‘]; if(vis[cur]) (dp[i]+=dp[j+1])%=MOD; } } printf("Case %d: %d ",T,dp[1]); } return 0; }
以上是关于[LA 3942] Remember the Word的主要内容,如果未能解决你的问题,请参考以下文章
LA 3942 && UVa 1401 Remember the Word (Trie + DP)
UVALive - 3942 Remember the Word[树状数组]