给出一个长度不超过300000的字符串 S,然后给出 n 个长度不超过100的字符串。

如果字符串可以多次使用,用这 n 个字符串组成 S 的方法数是多少?

比如样例中,abcd = a + b + cd = ab + cd

dp[i] 表示用这n个字符串构成,S中从 i ~ len之间的字母构成的子串,的可分解方案数。

如果存在一个位置 x >= i, 且 i~x 之间的字母是一个单词,那么dp[i] = ∑ ( dp[x] )

但是如果暴力枚举 i ~ x是不是一个单词,必然会TLE。这时我们就需要 Trie 树优化这个DP。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define maxn 400000 + 100
#define sigma_size 27
#define LL long long
#define MOD 20071027 int tot = ;
int trie[maxn][sigma_size], sum[maxn], dp[maxn]; void insert(char s[])
{
int root = ;
for (int i = ; s[i]; i++)
{
int id = s[i]-'a';
if (!trie[root][id])
{
sum[++tot] = ;
trie[root][id] = tot;
}
root = trie[root][id];
}
sum[root] = ;
} void found(char s[], int k)
{
int root = ;
for (int i = k; s[i]; i++)
{
int id = s[i]-'a';
if (!trie[root][id])
return;
root = trie[root][id];
if (sum[root])
dp[k] = (dp[k]+dp[i+])%MOD;
}
} int main()
{
char s[maxn];
int len, ca = ;
while(scanf("%s", s) != EOF)
{
char t[maxn];
int n;
scanf("%d", &n); memset(trie, , sizeof(trie));
memset(sum, , sizeof(sum));
for (int i = ; i <= n; i++)
{
scanf("%s", t);
insert(t);
} memset(dp, , sizeof(dp)); len = strlen(s); dp[len] = ;
for (int i = len-; i >= ; i--)
found(s, i); printf("Case %d: %d\n", ++ca, dp[]);
}
}

UVALive - 3942 (DP + Trie树)的更多相关文章

  1. Codeforces 615C Running Track(DP + Trie树)

    题目大概说给两个串,问最少要用多少个第一个串的子串(可以翻转)拼成第二个串. UVa1401,一个道理..dp[i]表示前缀i拼接成功所需最少的子串,利用第一个串所有子串建立的Trie树往前枚举转移. ...

  2. UVa1401 Remember the Word(DP+Trie树)

    题目给定一个字符串集合有几种方式拼成一个字符串. dp[i]表示stri...strlen-1的方案数 dp[len]=1 dp[i]=∑dp[j](stri...strj-1∈SET) 用集合的字符 ...

  3. 洛谷:P2292 [HNOI2004]L语言(DP+Trie树)

    P2292 [HNOI2004]L语言 题目链接:https://www.luogu.org/problemnew/show/P2292 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有 ...

  4. HNU 13108 Just Another Knapsack Problem DP + Trie树优化

    题意: 给你一个文本串,和一些模式串,每个模式串都有一个价值,让你选一些模式串来组成文本串,使获得的价值最大.每个模式串不止能用一次. 思路: 多重背包,枚举文本串的每个位置和模式串,把该模式串拼接在 ...

  5. Codeforces 633C Spy Syndrome 2(DP + Trie树)

    题目大概说给一个加密的字符串,加密规则是把原文转化成小写字母,然后各个单词反转,最后去掉空格.现在给几个已知的单词,还原加密的字符串. 和UVa1401一个道理.. 用dp[i]表示加密字符前i个字符 ...

  6. UVALive - 3942 (字典树)

    递推:$d(i) $表示从第$i$个字符开始到末尾的字符串(即后缀S[i...n])的分解方案数,则$d(i) = \sum {d(i + len(x))} $,其中字符串$x$代表S[i...n]的 ...

  7. Remember the Word UVALive - 3942 DP_字典树

    每个小单词的长度都是小于等于100的,这是个重要的突破口. Code: #include <cstdio> #include <algorithm> #include < ...

  8. UVALive 3942 Remember the Word 字典树+dp

    /** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5) ...

  9. UVALive - 3942 Remember the Word[Trie DP]

    UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...

随机推荐

  1. 爬虫(ProxyHandler)——代理

    工具:python3 步骤: 1)使用ProxyHandler()构建httpproxy_handler对象 2)使用build_opener(httpproxy_handler)构建opener 3 ...

  2. ci框架数据库相关函数

    返回查询影响的记录数 $res = $this->db->get_where('wx_life',array('id'=>$id)); $num = $res->num_row ...

  3. BeanCopier使用说明

    BeanCopier从名字可以看出了,是一个快捷的bean类复制工具类. 一 如何使用,我就直接丢代码了 public class BeanCopierTest { static SimpleDate ...

  4. SQL Server开窗函数之OVER子句、PARTITION BY 子句

    开窗函数与聚合函数一样,都是对行的集合组进行聚合计算.它用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同 ...

  5. 自动生成sql

    添加下面这个类 public static class GetAllAttribute<T> where T : class { public static string Names; p ...

  6. git-gui:使用终端打开以后出现错误提示 Spell checking is unavable

    参考链接:http://www.lai18.com/content/10706682.html 安装了git-gui,打开以后出现以下提示: Spell checking is unavable: e ...

  7. 一个例子说明Jsp三大重要内置对象的生命周期

    此处Jsp的三大内置对象指:request,session以及application.他们共有的方法:setAttribute,getAttribute,方法名和方法作用都是相同的,但是作用范围不一样 ...

  8. mitmproxy抓包软件在mac上边的安装

    官网介绍:mitmproxy is a free and open source interactive HTTPS proxy. mitmproxy 是用 Python 和 C 开发的一个中间人代理 ...

  9. JavaScript中三种字符串连接方式及其性能比较

    参考地址: https://www.cnblogs.com/programs/p/5554742.html 工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方 ...

  10. [选择排序] 时间复杂度O(n^2)

    思路:从未排序的序列中,找到最小的元素,放到序列的起始位置, 再从剩下没排序的里面,找到最小的,放到已经排序的末尾. 原地操作几乎是选择排序的唯一优点,当空间复杂度要求较高时,可以考虑选择排序:实际适 ...