UVA 1401 Remember the Word
字典树优化DP
| Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie.
Since Jiejie can't remember numbers clearly, he just uses sticks to help himself. Allowing for Jiejie's only 20071027 sticks, he can only record the remainders of the numbers divided by total amount of sticks.
The problem is as follows: a word needs to be divided into small pieces in such a way that each piece is from some given set of words. Given a word and the set of words, Jiejie should calculate the number of ways the given word can be divided, using the words in the set.
Input
The input file contains multiple test cases. For each test case: the first line contains the given word whose length is no more than 300 000.
The second line contains an integer S<tex2html_verbatim_mark> , 1
S
4000<tex2html_verbatim_mark> .
Each of the following S<tex2html_verbatim_mark> lines contains one word from the set. Each word will be at most 100 characters long. There will be no two identical words and all letters in the words will be lowercase.
There is a blank line between consecutive test cases.
You should proceed to the end of file.
Output
For each test case, output the number, as described above, from the task description modulo 20071027.
Sample Input
abcd
4
a
b
cd
ab
Sample Output
Case 1: 2
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string> using namespace std; const int MOD=;
const int maxn=; int m,dp[];
char str[]; struct Trie
{
int tot,root,child[maxn][];
bool flag[maxn];
Trie()
{
memset(child[],,sizeof(child[]));
flag[]=false;
root=tot=;
}
void Init()
{
memset(child[],,sizeof(child[]));
flag[]=false;
root=tot=;
}
void Insert(const char*str)
{
int *cur=&root;
for(const char *p=str;*p;p++)
{
cur=&child[*cur][*p-'a'];
if(*cur==)
{
*cur=++tot;
memset(child[tot],,sizeof(child[tot]));
flag[tot]=false;
}
}
flag[*cur]=true;
}
bool query(const char* str,int i)
{
int *cur=&root;
int l=;
for(const char*p=str;*p&&*cur;p++,l++)
{
cur=&child[*cur][*p-'a'];
if(flag[*cur])
{
dp[i]=(dp[i]+dp[i+l])%MOD;
}
}
return (*cur&&flag[*cur]);
}
}tree; int main()
{
int cas=;
while(scanf("%s",str)!=EOF)
{
int len=strlen(str);
scanf("%d",&m);
tree.Init();
while(m--)
{
char dic[];
scanf("%s",dic);
tree.Insert(dic);
}
memset(dp,,sizeof(dp));
dp[len]=;
for(int i=len-;i>=;i--)
{
tree.query(str+i,i);
}
printf("Case %d: %d\n",cas++,dp[]%MOD);
}
return ;
}
UVA 1401 Remember the Word的更多相关文章
- UVA 1401 - Remember the Word(Trie+DP)
UVA 1401 - Remember the Word [题目链接] 题意:给定一些单词.和一个长串.问这个长串拆分成已有单词,能拆分成几种方式 思路:Trie,先把单词建成Trie.然后进行dp. ...
- UVA 1401 Remember the Word(用Trie加速动态规划)
Remember the Word Neal is very curious about combinatorial problems, and now here comes a problem ab ...
- LA 3942 && UVa 1401 Remember the Word (Trie + DP)
题意:给你一个由s个不同单词组成的字典和一个长字符串L,让你把这个长字符串分解成若干个单词连接(单词是可以重复使用的),求有多少种.(算法入门训练指南-P209) 析:我个去,一看这不是一个DP吗?刚 ...
- UVA - 1401 Remember the Word(trie+dp)
1.给一个串,在给一个单词集合,求用这个单词集合组成串,共有多少种组法. 例如:串 abcd, 单词集合 a, b, cd, ab 组合方式:2种: a,b,cd ab,cd 2.把单词集合建立字典树 ...
- UVA - 1401 | LA 3942 - Remember the Word(dp+trie)
https://vjudge.net/problem/UVA-1401 题意 给出S个不同的单词作为字典,还有一个长度最长为3e5的字符串.求有多少种方案可以把这个字符串分解为字典中的单词. 分析 首 ...
- UVa 1401 (Tire树) Remember the Word
d(i)表示从i开始的后缀即S[i, L-1]的分解方法数,字符串为S[0, L-1] 则有d(i) = sum{ d(i+len(x)) | 单词x是S[i, L-1]的前缀 } 递推边界为d(L) ...
- uva 1401 dp+Trie
http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Itemid=8&page=show_problem& ...
- uva 1401
Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing ...
- 1401 - Remember the Word
注意到单词的长度最长100,其实最糟糕复杂度应该能到O(300005*100),需要注意的是在字典树上匹配单词时,一旦不匹配,则后面的就不会匹配,需要break出来(这个害我TLE查了半天,日!),还 ...
随机推荐
- Crimm Imageshop 2.3。
下载地址:http://files.cnblogs.com/Imageshop/ImageShop.rar 一款体积小,能绿色执行,又功能丰富的图像处理软件. Imageshop2.3为单EXE文件, ...
- Backtracking algorithm: rat in maze
Sept. 10, 2015 Study again the back tracking algorithm using recursive solution, rat in maze, a clas ...
- Java并发基础总结
并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可 交互性将大大改善.现代的PC都有多个CPU或一个CPU中有多 ...
- winform 用户控件、 动态创建添加控件、timer控件、控件联动
用户控件: 相当于自定义的一个panel 里面可以放各种其他控件,并可以在后台一下调用整个此自定义控件. 使用方法:在项目上右键.添加.用户控件,之后用户控件的编辑与普通容器控件类似.如果要在后台往窗 ...
- JAVA设计模式之3-抽象工厂模式
书接上文,简单工厂模式解决的是可以枚举种类的类的问题,但是带来了高耦合的问题,并且对类系列繁多无从下手,那么我们想起了一种方法,那就是抽象类,建一个抽象工厂,抽象工厂里的方法都是根据系列类的差异区分出 ...
- [LeetCode] Insert Interval 插入区间
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...
- 用vue.js学习es6(六):Iterator和for...of循环
一.Iterator (遍历器)的概念: 遍历器(Iterator)就是这样一种机制.它是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只 要部署Iterator接口,就可以完成遍历操 ...
- 聊聊 Apache 开源协议
摘要 用一句话概括 Apache License 就是,你可以用这代码,但是如果开源你必须保留我写的声明:你可以改我的代码,但是如果开源你必须写清楚你改了哪些:你可以加新的协议要求,但不能与我所 公布 ...
- js获取当前系统时间
Js获取当前日期时间及其它操作var myDate = new Date();myDate.getYear(); //获取当前年份(2位)myDate.getFullYear(); //获取完整的年份 ...
- 【BZOJ-2179&2194】FFT快速傅里叶&快速傅里叶之二 FFT
2179: FFT快速傅立叶 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2978 Solved: 1523[Submit][Status][Di ...