UVALive 3942 Remember the Word(字典树+dp)
2015-08-03 09:00
330 查看
题意:
给定一个长度不超过30000的字符串SS,然后给定n(n<=4000)个长度不超过100的字符串aia_i,问用aia_i组合成SS有多少种方案数,由于数量可能很大,最终结果mod 20071027。题解:
本来想学习一下字典树的,但是这题用到了dp。dp[i]dp[i]表示从ii开始到SS末尾有多少种组合方案。
那么dp公式为:dp[i]=∑dp[i+len(x)]dp[i]=\sum dp[i+len(x)] (x表示已经存在的字符串)。
所以我们可以从后往前递推,枚举dp[i]dp[i],然后再枚举中断点判断[i,j][i,j]的单词是否出现过,最后dp[0]dp[0]就是最终答案。
但是如果直接暴力,会超时,所以我们需要用字典树保存aia_i,每次查找单词是否出现就在字典树中查询,字典树查询的复杂的就是O(h),h为字符串的长度。
字典树:
向字典那样讲字符串保存在树当中,其中ch[i][j]表示在i状态下,输入字符j时,下个状态的位置是多少(类似于邻接表);val[i]表示i状态的时候是否是一个字符串的终点(也可以记录在这个位置终结的字符串的个数)。
其中ch[i][j]中j范围为字符集范围,例如小写字母是26个,0<=j<26;i比较大,最坏的情况下为len(str)∗max{len(ai)}len(str)*max\{len(a_i)\},这样很可能超出内存,不过这种情况基本不会出现,如果内存不够可以开更小的数组或者改用指针形式的字典树。
mymy codecode
[code]#pragma comment(linker, "/STACK:102400002,102400000") #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int MOD = 20071027; const int MAXN = 4005 * 100 + 100; int ch[MAXN][26]; int val[MAXN]; int sz; struct Trie { Trie() {sz = 1; memset(ch[0], 0, sizeof(ch)); } int idx(char c) { return c - 'a'; } void insert(char *s, int v = 1) { int u = 0; while(*s) { int c = idx(*s); if(!ch[u][c]) { memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; *s++; } val[u] = v; } bool find(char* s, int len) { int u = 0; for(int i = 0; i <= len; i++) { int c = idx(s[i]); if(!ch[u][c]) return false; u = ch[u][c]; } return val[u]; } }; char s[300005], word[105]; ll dp[300005]; int n; int main() { int cas = 1; while(scanf("%s", s) != EOF) { Trie trie; scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%s", word); trie.insert(word); } memset(dp, 0, sizeof(dp)); int len = strlen(s); dp[len] = 1; for(int i = len-1; i >= 0; i--) { for(int j = 0; j < 100 && i + j < len; j++) { if(trie.find(s + i, j)) { dp[i] = (dp[i+j+1] + dp[i]) % MOD; } } } printf("Case %d: %lld\n", cas++, dp[0]); } return 0; }
相关文章推荐
- Linux 解压zip命令
- 商品分类实现无限级
- java集群优化——Nginx+tomcat集群配置-理论篇
- CodeForces 2A
- Killing Monsters(不使用线段树)HDU4970
- 详解Java中final的用法
- 快速安装Ruby on Rails的简明指南
- [周赛] Heros and Swords
- JVM的相关知识整理和学习
- UML类图中的六种关系及实例
- 构建亿级前端读服务
- JQuery总结
- 关于KB3074683的问题
- iOS开发-地图01-corelocation
- 高级纹理映射知识汇总
- PHP Socket 编程过程详解
- 动态创建按钮
- echo选项
- mysql对ip地址的处理方法
- 移动对象过程中加入动画效果