[LA 3942] Remember the Word

Posted newera

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LA 3942] Remember the Word相关的知识,希望对你有一定的参考价值。

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

 

以上是关于[LA 3942] Remember the Word的主要内容,如果未能解决你的问题,请参考以下文章

LA 3942 Remember the word

LA 3942 && UVa 1401 Remember the Word (Trie + DP)

UVA-3942 Remember the Word

UVALive - 3942 Remember the Word[树状数组]

UVALive - 3942 Remember the Word[Trie DP]

3942 - Remember the Word