码迷,mamicode.com
首页 > 其他好文 > 详细

[LA 3942] Remember the Word

时间:2018-06-30 20:22:46      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:++   bool   ext   自己   class   模式匹配   转移   \n   ace   

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

标签:++   bool   ext   自己   class   模式匹配   转移   \n   ace   

原文地址:https://www.cnblogs.com/newera/p/9248498.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!