1. 程式人生 > >[LA 3942] Remember the Word

[LA 3942] Remember the Word

include IT bool c++ lan 模式匹配 ati std 前綴

Link:

LA 3942 傳送門

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\n",T,dp[1]); } return 0; }

[LA 3942] Remember the Word