注意到单词的长度最长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. 【译】Android系统简介—— Activity

    续上一篇,继续介绍Android系统.上一篇: [译]Android系统简介 本文主要介绍构建Android应用的一些主要概念: Activity Activity是应用程序中一个单独的有UI的页面( ...

  2. CrossDomain.xml的作用及其简单用法

    使用crossdomain.xml让Flash可以跨域传输数据 本文来自http://www.mzwu.com/article.asp?id=975 一.概述 位于www.mzwu.com域中的SWF ...

  3. MySQL Server-id的作用

    1. mysql同步的数据中是包含server-id的,用于标识该语句最初是从哪个server写入的,因此server-id一定要有的 2. 每一个同步中的slave在master上都对应一个mast ...

  4. mutable和volatile关键字

    1.mutable 在C++中,mutable是为了突破const的限制而设置的.被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其 ...

  5. STL学习二:Vector容器

    1.Vector容器简介 vector是将元素置于一个动态数组中加以管理的容器. vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法,这个等下会详讲). vector尾部添 ...

  6. Leetcode-Read N Characters Given Read4 II

    The API: int read4(char *buf) reads 4 characters at a time from a file. The return value is the actu ...

  7. iOS 23 种设计模式

    设计模式主要分三个类型:创建型.结构型和行为型. 其中创建型有: 一.Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 二.Abstract Factory,抽象工厂 ...

  8. Android Studio 单刷《第一行代码》系列 01 —— 第一战 HelloWorld

    前言(Prologue) 本系列将使用 Android Studio 将<第一行代码>(书中讲解案例使用Eclipse)刷一遍,旨在为想入坑 Android 开发,并选择 Android ...

  9. 使用GitHub建立自己的个人主页

    1.建仓库 在自己的库里建一个hujun123qwe.github.io的库 即可以使用这个名字当网址访问. 2.写内容 在库里建一个首页文件 index.html 这个个人主页只支持静态的内容,像p ...

  10. Sql例子Sp_ExecuteSql 带参数

    Declare @i int, @projectCount int ) --参数 ) ) ) ) ) ) --循环变量起始 --得到所有的项目 select @projectCount = count ...