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是从最后一 ...
随机推荐
- 【336】Tutorial of Endnote
Now I start to use Endnote to manage my literatures and I need to learn how to use it. Below is some ...
- 播放一个wav文件
use mmsystem;SndPlaySound('hello.wav',SND_FILENAME or SND_SYNC) ///////////////////////////////////u ...
- Java发送HTTPS请求
前言 上篇文章介绍了 java 发送 http 请求,大家都知道发送http是不安全的 .我也是由于对接了其他企业后总结了一套发送 https的工具.大家网上找方法很多的,但是可不是你粘过来就能用啊, ...
- python 形参
def fun(x="dx",y="dy"): print "fun------" print x print y fun()fun(&qu ...
- Dubbo 分布式服务框架
要想了解Dubbo是什么,我们不防先了解它有什么用. 使用场景:比如我想开发一个网上商城项目,这个网上商城呢,比较复杂,分为pc端web管理后台,微信端销售公众号,那么我们分成四个项目,pc端网站,微 ...
- 查看dns节点的内存是否够用
dmesg查看是否有报错
- Appium客户端,命令行启动server
目标:通过命令行启动Appium的server 1.通过命令行安装的Appium 直接命令行输入appium即可启动服务 2.安装的Appium客户端 可以查看客户端中打印的启动日志: ...
- 安装和使用iOS的包管理工具CocoaPods
CocoaPods是ruby实现的,需要用ruby进行安装,mac自带ruby,如果没有ruby的需要先安装ruby. 安装CocoaPods命令 安装CocoaPods命令:sudo gem i ...
- suse安装gcc,升级到4.8.5
前面这些是挂载iso,如果iso可以使用,就不需要下面几步. cd /etc/zypp/repos.d mkdir iso chmod -R 777 iso mount -o loop /media/ ...
- 97. Interleaving String (String; DP)
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example,Given:s1 = ...