注意到单词的长度最长100,其实最糟糕复杂度应该能到O(300005*100),需要注意的是在字典树上匹配单词时,一旦不匹配,则后面的就不会匹配,需要break出来(这个害我TLE查了半天,日!),还有,要注意strlen的时候,那个api的复杂度貌似是O(n)的,题目中提到输入数据的不同的test case之间有一个blank line,我理解成输出不同case之间要回车,OJ居然没判成PE,而是判成WA,这两天题写的真蛋疼(吐槽下)。

#include <cstdio>
#include <cstring>
#include <vector>
#include <stack>
#include <iostream>
using namespace std; const int MAXN = ;
const int M = ; typedef long long int64; char ch[MAXN];
int64 dp[MAXN]; int id[ * ][], cnt;
bool flag[ * ]; class DicNode {
public:
bool flag;
DicNode *sons[];
DicNode() {
flag = false;
memset(sons, NULL, sizeof(sons));
}
}; class DicTree2 {
public:
DicTree2() {
cnt = ;
memset(id, -, sizeof(id));
memset(flag, false, sizeof(flag));
}
~DicTree2() { }
void insert(const char *s) {
int len = strlen(s);
int node = ;
for (int i = ; i < len; i++) {
if (id[node][s[i] - 'a'] == -) {
id[node][s[i] - 'a'] = cnt++;
}
node = id[node][s[i] - 'a'];
if (i == len - ) {
flag[node] = true;
}
}
}
bool query(const char *s) {
int len = strlen(s);
int node = ;
for (int i = ; i < len; i++) {
if (id[node][s[i] - 'a'] == -) {
return false;
}
node = id[node][s[i] - 'a'];
}
return flag[node];
}
int64 f(int b, int len) {
if (dp[b] != -) return dp[b];
dp[b] = ;
if (b == len) return dp[b] = ;
int node = ;
for (int i = b; i < len; i++) {
if (id[node][ch[i] - 'a'] != -) {
node = id[node][ch[i] - 'a'];
if (flag[node]) dp[b] = (dp[b] + f(i + , len)) % M;
} else {
break;
}
}
return dp[b];
}
}; class DicTree {
public:
DicNode *root;
DicTree() {
root = new DicNode();
}
~DicTree() {
if (NULL != root) {
free(root);
}
}
void free(DicNode *node) {
for (int i = ; i < ; i++) {
if (node->sons[i] != NULL) {
free(node->sons[i]);
}
}
delete node;
}
void insert(const char *s) {
int len = strlen(s);
DicNode *node = root;
for (int i = ; i < len; i++) {
if (node->sons[s[i] - 'a'] == NULL) {
node->sons[s[i] - 'a'] = new DicNode();
}
node = node->sons[s[i] - 'a'];
if (i == len - ) {
node->flag = true;
}
}
}
bool query(const char *s) {
int len = strlen(s);
DicNode *node = root;
for (int i = ; i < len; i++) {
if (node->sons[s[i] - 'a'] == NULL) {
return false;
}
node = node->sons[s[i] - 'a'];
}
return node->flag;
}
int64 f(int b, int len) {
if (dp[b] != -) return dp[b];
dp[b] = ;
if (b == len) return dp[b] = ;
DicNode *node = root;
for (int i = b; i < len; i++) {
if (node->sons[ch[i] - 'a'] != NULL) {
node = node->sons[ch[i] - 'a'];
if (node->flag) dp[b] = (dp[b] + f(i + , len)) % M;
} else {
break;
}
}
return dp[b];
}
}; int main() {
int c = ;
while (scanf("%s", ch) != EOF) {
int s;
scanf("%d", &s);
DicTree dic;
for (int i = ; i < s; i++) {
char str[];
scanf("%s", str);
dic.insert(str);
}
memset(dp, -, sizeof(dp));
printf("Case %d: %lld\n", ++c, dic.f(, strlen(ch)));
}
}

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

    字典树优化DP                                Remember the Word Time Limit: 3000MS   Memory Limit: Unknown ...

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

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

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

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

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

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

  6. Uva1401(字典树)

    1401 - Remember the Word Time limit: 3.000 seconds Neal is very curious about combinatorial problems ...

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

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

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

  9. 大白书 209 remember the word

    F - Remember the Word Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Sub ...

随机推荐

  1. mercurial(hg)使用

    # 版本管理软件的比较 svn 每个目录下建一个.svn目录实在是不爽. git 分支管理非常方便,但没感觉有什么用,主要还是在修改前提交一次代码, 等后悔时再回来,没什么其他的目的.关键是中文乱码问 ...

  2. Oracle利用数据泵迁移用户

    一.利用数据泵将数据导出 1.1.确定字符集: select * from v$nls_parameters; 或 select userenv('language') from dual; 1.2. ...

  3. AIR串口通信

    最近公司的项目中需要用到串口通信,项目是用基于AIR的,AIR本身是不支持串口通信的,本想用 c#或java另写一个负责串口通信的模块,又感觉很烦不想那么弄,就想到了ANE.可惜以前也没弄过 ANE, ...

  4. Gartner2014年魔力象限(商业智能和分析平台)

  5. Surrounded Regions

    Surrounded Regions Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A ...

  6. LintCode-Hash Function

    In data structure Hash, hash function is used to convert a string(or any other type) into an integer ...

  7. DB天气app冲刺二阶段第八天

    今天突然感觉应该做收尾工作了 因为马上就要考试了,时间一下子就不够用了.. 今天主要修复了一下bug,然后天气基本能够实时准确了,就是多功能按钮还是没有弄好 准备简化一下功能. 明天看看还有什么需要改 ...

  8. Careercup - Google面试题 - 5735304249999360

    2014-05-03 23:18 题目链接 原题: Insert a element in a sorted circular linked list 题目:题意简单明了,向一个有序的循环单向链表中插 ...

  9. 利用Vagrant搭建多平台环境

    Vagrant 是一个创建和分发虚拟化开发环境的工具,使用ruby编写,本身并不包含虚拟机管理软件,因此我们需要配合Vagrant安装一个虚拟机软件.Vagrant支持VMware, Virtual ...

  10. c++ 关于换行符

    windows: \r\n linux: \n mac: \r http://blog.chinaunix.net/uid-12706763-id-10830.html 不同的OS有不同的换行符: O ...