UVALive 3942 Remember the Word 前缀树Trie
来源:互联网 发布:电脑插件软件 编辑:程序博客网 时间:2024/06/06 09:34
Remember the Word
给出一个由S个不同单词组成的字典和一个长字符串,把这个字符串分解成若干个单词的连接(单词可以重复使用),有多少种方法
sample input:
abcd
4
a
b
cd
ab
sampsample output
Case 1 : 2解题思路:
这题为什么会用前缀树来做呢,既然是要找有多少种分解方法,其实关键点还是后面的递推关系来找的
d[i] = (d[i]+d[i+len[p[j]]])%MOD ;对于原串从位置i开始的分解方法,等于从i开始找到多少个字符串然后i+找到的字符串的长度位置的d[i+len]因为是从后往前找,所以这个位置的值
是已知的,所以最后的d[0]就是本题的解。
那么怎么找字符串?暴力循环肯定会超时,所以这就需要一个非常好的数据结构来帮助我们快速的找到字符串
那就是前缀树了Trie,我们需要它做的就是根据开始位置i往后找出所有的可以分解的单词, 获取他们的长度用于最后的递推。
这样是非常节省时间的
思路就是这些,刚开始会很难想,但是相信这样的题目做多了,会手到擒来的。
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;const int maxnode = 400010 ;const int sigma_size = 26 ;struct Trie{ int ch[maxnode][sigma_size]; int val[maxnode] ; int sz ; void clear(){///构造器 sz = 1 ;///节点总数 memset(ch,0,sizeof(ch));///节点矩阵 } int idx(char c){///字符c的编号 return c-'a' ; } void insert(const char *s,int v){ int u = 0 , n = strlen(s);///初始根节点 for(int i=0;i<n;i++){ int c = idx(s[i]); if(!ch[u][c]){///如果节点不存在 memset(ch[sz],0,sizeof(ch[sz]));///新位置清空 val[sz] = 0 ;///节点的附加值初始为0 ch[u][c] = sz++ ;///赋值,让树连上这个新节点 } u = ch[u][c] ;///节点往下走 } val[u] = v ;///节点最后的附加信息代表是字符串编号 }///找字符串s的长度不超过len的前缀void find(const char *s,int len,vector<int>& ans){ int u = 0 ; for(int i = 0;i<len;i++){ if(s[i]=='\0')break ; int c = idx(s[i]); if(!ch[u][c])break ; u = ch[u][c] ; if(val[u]!=0)ans.push_back(val[u]); } }};const int maxl = 300000 + 10; // 文本串最大长度const int maxw = 4000 + 10; // 单词最大个数const int maxwl = 100 + 10; // 每个单词最大长度const int MOD = 20071027;int d[maxl];int len[maxw];int S ;char text[maxl];char word[maxwl];Trie trie ;int main(){ int cas = 1 ; while(~scanf("%s%d",text,&S)){ trie.clear(); for(int i=1;i<=S;i++){ scanf("%s",word); len[i] = strlen(word); trie.insert(word,i); } memset(d,0,sizeof(d)); int L = strlen(text); d[L] = 1 ; for(int i = L -1 ;i>=0;i--){ vector<int>p; trie.find(text+i,L-i,p); for(int j=0;j<p.size();j++){ d[i] = (d[i]+d[i+len[p[j]]])%MOD ; } } printf("Case %d: %d\n", cas++, d[0]); } return 0;}
0 0
- UVALive 3942 Remember the Word 前缀树Trie
- UVALive - 3942 Remember the Word (Trie)
- uvalive 3942 - Remember the Word(Trie)
- UVALive - 3942 Remember the Word Trie
- UVALive - 3942 Remember the Word(trie + dp)
- UVALive 3942 Remember the Word 字典树DP&&前缀树
- Remember the Word - UVaLive 3942 Trie树+dp
- UVALive - 3942 - Remember the Word (Trie树)
- UVALive 3942 Remember the Word(trie + dp)
- UVA-1401 - Remember the Word -----Trie前缀树
- UVALIVE 3942 Remember the Word 字典树
- uvaLive 3942 Remember the Word 字典树
- UVA 3942 Remember the Word(Trie树)
- UVALive 3942 (LA 3492) Remember the Word Trie树 + 记忆化搜索
- UVALive 3942 Remember the Word
- UVALive 3942 - Remember the Word(DP,数组Trie+指针Trie)
- Remember the Word (trie)
- Remember The Word-Trie
- Android Studio Gradle Build Running 特别慢的问题
- Lambda架构实现数据实时更新
- 网站测速服务 查看自己网站在全球的打开速度
- Android学习之路------广播的注册方式
- 蓝桥杯:字符串替换
- UVALive 3942 Remember the Word 前缀树Trie
- Ajax实现提交form表单
- 索引的应用
- ios开发之View属性hidden, opaque, alpha, opacity的区别
- Java实现从学校教务网上爬取数据(一)—— 虚拟登陆
- HDU 搜索 2952
- gcc 内联函数
- [Android L]SEAndroid加强Androd安全性背景概要及带来的影响
- 几个常用在线托管地址