字典树优化DP

                               Remember the Word
Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

[Submit]   [Go Back]   [Status]

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> , 1S4000<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的更多相关文章

  1. UVA 1401 - Remember the Word(Trie+DP)

    UVA 1401 - Remember the Word [题目链接] 题意:给定一些单词.和一个长串.问这个长串拆分成已有单词,能拆分成几种方式 思路:Trie,先把单词建成Trie.然后进行dp. ...

  2. UVA 1401 Remember the Word(用Trie加速动态规划)

    Remember the Word Neal is very curious about combinatorial problems, and now here comes a problem ab ...

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

    题意:给你一个由s个不同单词组成的字典和一个长字符串L,让你把这个长字符串分解成若干个单词连接(单词是可以重复使用的),求有多少种.(算法入门训练指南-P209) 析:我个去,一看这不是一个DP吗?刚 ...

  4. UVA - 1401 Remember the Word(trie+dp)

    1.给一个串,在给一个单词集合,求用这个单词集合组成串,共有多少种组法. 例如:串 abcd, 单词集合 a, b, cd, ab 组合方式:2种: a,b,cd ab,cd 2.把单词集合建立字典树 ...

  5. UVA - 1401 | LA 3942 - Remember the Word(dp+trie)

    https://vjudge.net/problem/UVA-1401 题意 给出S个不同的单词作为字典,还有一个长度最长为3e5的字符串.求有多少种方案可以把这个字符串分解为字典中的单词. 分析 首 ...

  6. 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) ...

  7. uva 1401 dp+Trie

    http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. uva 1401

    Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing ...

  9. 1401 - Remember the Word

    注意到单词的长度最长100,其实最糟糕复杂度应该能到O(300005*100),需要注意的是在字典树上匹配单词时,一旦不匹配,则后面的就不会匹配,需要break出来(这个害我TLE查了半天,日!),还 ...

随机推荐

  1. Quartz实现任务调度

    一.任务调度概述 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情,核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作,任务调度涉及多线程并发. ...

  2. Openjudge 1.13-21:最大质因子序列(每日两水)

    总时间限制:  1000ms 内存限制:  65536kB 描述 任意输入两个正整数m, n (1 < m < n <= 5000),依次输出m到n之间每个数的最大质因子(包括m和n ...

  3. html tab页面切换事件。

    $(document).bind("visibilitychange",function(e){ //只对tab页面切换有效 //document.visibilityState ...

  4. IT培训行业揭秘(五)

    前面说了一大堆,简单揭露了一些目前培训行业鱼龙混在的情况,那么今天我就站在一个即将毕业的大学生角度来谈谈如何选择一个靠谱的培训机构. 你即将大学毕业了,在大学里面浑浑噩噩的混了几年,马上就要离开校园, ...

  5. IFC格式简介

    IFC是一个数据交换标准, 用于不同系统交换和共享数据.当需要多个软件协同完成任务时, 不同系统之间就会出现数据交换和共享的需求.这时, 工程人员都希望能将工作成果(这里就是工程数据), 从一个软件完 ...

  6. jqGrid jqGrid分页参数+条件查询

    HTML <div class="row"> <div class="col-sm-20"> <form id="for ...

  7. js小练习去掉指定的字符组成一句话输出

    今天在codewar做练习题时,要求写一个函数把一个字符串去掉WUB这些多余的字符然后把剩下的组成一句话输出,如传入"WUBAWUBBWUBCWUB"后返回"A B C& ...

  8. (转)git常见错误

    如果输入$ Git remote add origin git@github.com:djqiang(github帐号名)/gitdemo(项目名).git 提示出错信息:fatal: remote ...

  9. SpringCloud: 服务发现

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #e4af0a } sp ...

  10. 重复安装相同包名APK出现的问题。

    一. INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES 这样的问题主要是签名冲突造成的,比如你使用了ADB的debug权限签名,但后来使用标准sign签名后 ...