LA 3942 && UVa 1401 Remember the Word (Trie + DP)
题意:给你一个由s个不同单词组成的字典和一个长字符串L,让你把这个长字符串分解成若干个单词连接(单词是可以重复使用的),求有多少种。(算法入门训练指南-P209)
析:我个去,一看这不是一个DP吗?刚开始交一直是runtime error,找了好久,一直以为是数组开小了,不断增大还是这样,后来发现我用了char类型。。。下面分析这个题目
应该不难想到这个状态转移方程:
d(i) = sum{d(i+len(x))|单词x是s[i...L]的前缀},其中len(x)是长度。d(i)表示从字符i开始的字符串(也就是后缀s[i...L])的种数。
很明显我们是从后往前递推的,d(i)的种数应该是由d(i)和d(i+len(x))的和组成的(想想为什么,不理解可以画个图分析一下)。
如果先枚举x,再判断它是不是s[i...L]的前缀,时间复杂度太高了。所以换一个思路,先把单词组成Tire(前缀树),然后试着在Tire中去找s[i..L]。具体参考代码。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring> using namespace std;
const int maxn = 4000 * 100 + 10; // 4000个单词,每个单词最长是100,最多就有这么多
const int maxm = 300010;
const int mod = 20071027;
int d[maxm];
char ss[maxm], t[110]; struct Tire{
int ch[maxn][26];
int val[maxn];
int sz;
void init() { sz = 1; memset(val, 0, sizeof(val)); memset(ch[0], 0, sizeof(ch[0])); } //初始化
int idx(char c){ return c - 'a'; } //获得编号 void inser(char *s){ // 插入
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]));
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = n;
} void quary(char *s, int i, int n){ // 查找
int u = 0;
for(int j = 0; j < n; ++j){
int c = idx(s[j]);
if(!ch[u][c]) return ;
u = ch[u][c];
if(val[u]) d[i] = (d[i] + d[i + val[u]]) % mod;
}
}
};
Tire tire; int main(){
int n, kase = 0;
while(~scanf("%s %d", ss, &n)){
tire.init(); //一定要初始化,刚开始Tire定义在里面,一运行就崩。。。我也是醉了 for(int i = 0; i < n; ++i){
scanf("%s", t);
tire.inser(t);
} memset(d, 0, sizeof(d));
int len = strlen(ss);
d[len] = 1;// 这个地方是边界,注意初始化 for(int i = len-1; i >= 0; --i)
tire.quary(ss+i, i, len-i); //递推种数
printf("Case %d: %d\n", ++kase, d[0]);
}
return 0;
}
LA 3942 && UVa 1401 Remember the Word (Trie + DP)的更多相关文章
- UVA 1401 - Remember the Word(Trie+DP)
UVA 1401 - Remember the Word [题目链接] 题意:给定一些单词.和一个长串.问这个长串拆分成已有单词,能拆分成几种方式 思路:Trie,先把单词建成Trie.然后进行dp. ...
- UVA 1401 Remember the Word(用Trie加速动态规划)
Remember the Word Neal is very curious about combinatorial problems, and now here comes a problem ab ...
- UVA - 1401 Remember the Word(trie+dp)
1.给一个串,在给一个单词集合,求用这个单词集合组成串,共有多少种组法. 例如:串 abcd, 单词集合 a, b, cd, ab 组合方式:2种: a,b,cd ab,cd 2.把单词集合建立字典树 ...
- UVALive - 3942 Remember the Word[Trie DP]
UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...
- UVA 1401 Remember the Word
字典树优化DP Remember the Word Time Limit: 3000MS Memory Limit: Unknown ...
- 【UVA1401】Remember the Word Trie+dp
题目大意:给定一个字符串和一个字符串集合,问从集合中选出若干个串组成给定母串的不同方案数. 题解:有些类似于背包问题.状态很好表示,为:\(dp[i]\) 表示母串前 i 个字符的不同方案数,因此,有 ...
- UVA - 1401 | LA 3942 - Remember the Word(dp+trie)
https://vjudge.net/problem/UVA-1401 题意 给出S个不同的单词作为字典,还有一个长度最长为3e5的字符串.求有多少种方案可以把这个字符串分解为字典中的单词. 分析 首 ...
- Trie + DP LA 3942 Remember the Word
题目传送门 题意:(训练指南P209) 问长字符串S能由短单词组成的方案数有多少个 分析:书上的做法.递推法,从后往前,保存后缀S[i, len-1]的方案数,那么dp[i] = sum (dp[i+ ...
- UVA 3942 Remember the Word (Trie+DP)题解
思路: 大白里Trie的例题,开篇就是一句很容易推出....orz 这里需要Trie+DP解决. 仔细想想我们可以得到dp[i]=sum(dp[i+len[x]]). 这里需要解释一下:dp是从最后一 ...
随机推荐
- 模板引擎-freemarker
Freemarker 是一款模板引擎,是一种基于模版生成静态文件的通用 工具,它是为java程序员提供的一个开发包. 可通过将Word或者Excel模板另存为xml格式,在其中修改要替换的内容. 基本 ...
- Mysql 知识(1)
1. 请简洁地描述下MySQL中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别? 答: SQL标准定义的四个隔离级别为:read uncommited,read committed,rep ...
- 程序员教程-9章-C程序设计
目录结构: 9.1 C语言基础 9.1.1 数据类型 1 基本数据类型 2 数组.字符数组与字符串 3 枚举类型 4 结构体.共用体和typedef 9.1.2 运算符与表达式 9.1.3 输入/输出 ...
- Apache Hive 执行HQL语句报错 ( 10G )
# 故障描述: hive > , ) as uuid, count(distinct(request_body["uuid"])) as count from log_bft ...
- centos7 端口转发
firewall-cmd --add-masquerade firewall-cmd --add-forward-port=port=3001:proto=tcp:toaddr=172.17.18 ...
- 大型运输行业实战_day07_1_订单查看实现
1.业务分析 每个在窗口售票的售票员都应该可以随时查看自己的售票信息 简单的界面入口如图所示: 对应的html代码: <button onclick="orderDetail()&qu ...
- clipboard.js复制文字
A-固定内容: <script type="text/javascript" src="script/clipboard.min.js"></ ...
- fusioncharts 破解方法(转载)
FusionCharts是一个Flash的图表组件,它可以用来制作数据动画图表,其中动画效果用的是Adobe Flash 8 (原Macromedia Flash的)制作的flash , Fusion ...
- SSH三大框架需要的配置文件
1. Struts2框架 * 在web.xml中配置核心的过滤器 <filter> <filter-name>struts2</filter-name> <f ...
- 对于某些浏览器不支持placeholder的解决办法
$(function () { if (!placeholderSupport()) { $('[placeholder]').focus(function () { var input = $(th ...