给出一个长度不超过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. #1369 : 网络流一·Ford-Fulkerson算法 模板题

    http://hihocoder.com/problemset/problem/1369?sid=1108721 别人都说先学网络流再学二分图,但是我先学了二分图的,感觉网络流好高端啊. 首先对于原图 ...

  2. 《四 spring源码》利用TransactionManager手写spring的aop

    事务控制分类 编程式事务控制          自己手动控制事务,就叫做编程式事务控制. Jdbc代码: Conn.setAutoCommite(false);  // 设置手动控制事务 Hibern ...

  3. 基本类型包装类、System类、Math类、Arrays类、大数据运算

    1 基本类型包装类 Java中想对8种基本数据类型进行复杂操作很困难. 实际程序界面上用户输入的数据都是以字符串类型进行存储的. 程序开发中,需要把字符串转换成指定的基本数据类型. 1.1基本数据类型 ...

  4. text-transform字母大小写属性设置

    text-transform: none: 默认  不设置,全是小写 capitalize: 每个单词以大写字母开头 uppercase: 全部是大写字母 lowercase:  全部是小写字母 in ...

  5. 监听textarea数值变化

    监听textarea数值变化 $('#id').bind('input propertychange', function(){ //TODO });

  6. <Android HAL 之路> HAL 简介

    HAL层概述 名称: HAL, Hardware Abstracting Layer,中文名字:硬件抽象层. 作用:对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节.向上衔接Andro ...

  7. ios 利用kvc 监听可变数组变化

    KVO键值监听: Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观 ...

  8. Linux:linux下建ftp用户,并限制用户访问路径

    安装:ftp安装部分,操作步骤如下: 可以使用yum命令直接安装ftp # yum install vsftpd ftp服务的开启与关闭命令: 开启:# service vsftpd start 关闭 ...

  9. 微软打造了全球最大的Git代码库

    丹棱君有话说:今年 2 月,微软宣布将用 Git 管理 Windows 源代码.随后,Visual Studio 宣布开发 “Git 虚拟文件系统(GVFS)”,并将在终极项目和超大型团队中推行 Gi ...

  10. SqlServer自定义排序

    在实际项目中,有时会碰到数据库SQL的特殊排序需求,举几个例子,作为参考. 1.自定义优先级 一种常见的排序需求是指定某个字段取值的优先级,根据指定的优先级展示排序结果.比如如下表: Create T ...