LA 3942 Remember the Word(前缀树&树上DP)
3942 - Remember the Word
Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie.
Since Jiejie can't remember numbers clearly, he just uses sticks to help himself. Allowing for Jiejie's only 20071027 sticks, he can only record the remainders of the numbers divided by total amount of sticks.
The problem is as follows: a word needs to be divided into small pieces in such a way that each piece is from some given set of words. Given a word and the set of words, Jiejie should calculate the number of ways the given word can be divided, using the words in the set.
Input
The input file contains multiple test cases. For each test case: the first line contains the given word whose length is no more than 300 000.
The second line contains an integer S , 1
S
4000 .
Each of the following S lines contains one word from the set. Each word will be at most 100 characters long. There will be no two identical words and all letters in the words will be lowercase.
There is a blank line between consecutive test cases.
You should proceed to the end of file.
Output
For each test case, output the number, as described above, from the task description modulo 20071027.
Sample Input
abcd
4
a
b
cd
ab
Sample Output
Case 1: 2
题意:
该题为大白(刘汝佳。入门经典训练指南)上一道例题。p209。
思路:
dp[i]=sum(dp[i+len(x)])
dp[i]表示从字符i开始的字符串即后缀(s[i..L])的分解方案数。
x为是(s[i..L]的前缀。
详细见代码:
#include <iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int md=400110;//单词数乘上单词长度。顶多一个单词一条路径
const int ssz=26;
const int maxn=300010;
const int mod=20071027;
char words[maxn];
int dp[maxn]; struct Trie
{
int ch[md][ssz];
int val[md];
int sz;
void init()
{
sz=1;
val[0]=0;
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]);
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=n;//可以传参数初始化
}
void sear(char *s,int p,int len)
{
int u=0;
for(int i=0; i<len; i++)//字符一个一个查找
{
int c=idx(s[i]);
if(!ch[u][c])//前缀搜完
return ;
u=ch[u][c];
if(val[u])
dp[p]=(dp[p]+dp[p+val[u]])%mod;
}
}
} tree;
int main()
{
int i,s,len,cas=1;
char tmp[110]; while(~scanf("%s",words))
{
scanf("%d",&s);
len=strlen(words);
tree.init();//开始忘了初始化。调了半天。。。。。
dp[len]=1;//注意这个位置的初始化!
for(i=0; i<s; i++)
{
scanf("%s",tmp);
tree.inser(tmp);
}
for(i=len-1; i>=0; i--)
{
dp[i]=0;
tree.sear(words+i,i,len-i);
}
printf("Case %d: %d\n",cas++,dp[0]);
}
return 0;
}
LA 3942 Remember the Word(前缀树&树上DP)的更多相关文章
- LA 3942 - Remember the Word 字典树+DP
看题传送门:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show ...
- bzoj 2286 [Sdoi2011]消耗战(虚树+树上DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2286 [题意] 给定一棵树,切断一条树边代价为ci,有m个询问,每次问使得1号点与查询 ...
- 洛谷P4426 毒瘤 [HNOI/AHOI2018] 虚树+树上dp
正解:虚树+树上dp 解题报告: 传送门! 首先解释一下题意趴,,,语文70pts选手已经开始看不懂题辣QAQ 大概就是个给一个图,求独立集方案,且保证图是联通的,边的数量最多只比点多10 首先思考如 ...
- luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分)
luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分) Luogu 题解时间 $ k $ 条边权为 $ 0 $ 的边. 是的,边权为零. 转化成选正好 $ k+1 $ 条链. $ ...
- [LA 3942] Remember the Word
Link: LA 3942 传送门 Solution: 感觉自己字符串不太行啊,要加练一些蓝书上的水题了…… $Trie$+$dp$ 转移方程:$dp[i]=sum\{ dp[i+len(x)+1]\ ...
- UVALive 3942 Remember the Word 字典树+dp
/** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5) ...
- 【题解】彩色树 51nod 1868 虚树 树上dp
Prelude 题目在这里:ο(=•ω<=)ρ⌒☆ Solution 蒟蒻__stdcall的第一道虚树题qaq. 首先很容易发现,这个排列是假的. 我们只需要求出每对点之间的颜色数量,然后求个 ...
- LA 3942 - Remember the Word (字典树 + dp)
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- Trie + DP LA 3942 Remember the Word
题目传送门 题意:(训练指南P209) 问长字符串S能由短单词组成的方案数有多少个 分析:书上的做法.递推法,从后往前,保存后缀S[i, len-1]的方案数,那么dp[i] = sum (dp[i+ ...
随机推荐
- cmake 学习笔记(二)
在 Cmake学习笔记一 中通过一串小例子简单学习了cmake 的使用方式. 这次应该简单看看语法和常用的命令了. 简单的语法 注释 # 我是注释 命令语法 COMMAND(参数1 参数2 ...) ...
- 用了好多年的XP换成了Win7
因为懒,所以工作的笔记本XP一直没有换 网卡故障被逼无奈正好升成Win7 顺便看了一下市场占有率,Win7已经百分之四十多了,去年就超过XP了 不过XP也够持久的了,都十二年了,有这样长寿的产品对哪家 ...
- sqlserver 三种恢复模式
sql server数据库提供了三种恢复模式:完整,简单和大容量日志,这些模式决定了sql server如何使用事务日志,如何选择它要记录的操作,以及是否截断日志.截断事务日志是删除己执行事务并把该日 ...
- 在Windows下github展示代码
最近大爱Web编程,于是寻找各种代码中,然后就发现了GitHub这个网站,如果你知道Google Code,那么你就知道这个GitHub是做什么的了.不过GitHub主要是用作基于Git的分布式版本管 ...
- C语言深度剖析---预处理(define)(转载)
1.数值宏常量 #define宏定义是个演技非常高超的替身演员,但也会耍大牌的,所以我们使用它要慎之又慎.它可以出现在代码的任何地方,从本行宏定义开始,以后的代码都认识宏了:也可以把任何东西都 ...
- 关于jsonp(~~原理和理解)
JSON和JSONP 与XML相比,JSON是一个轻量级的数据交换格式.JSON对于JavaScript开发人员充满魅力的原因在于JSON本身就是Javascript中的对象. 例如一个ticker对 ...
- Mojo 自动发布接口
get '/api/auto_publish/publish' => sub{ my $c = shift; my $env = $c->param('env'); my $app = $ ...
- ReviewBoard安装和配置札记
眼下部门还没有採用Pair Programming那种时时刻刻都在review代码的工作方式,代码Review多採用走查方式,即代码写完后召开一个Code Review的Meeting,集中时间和经验 ...
- stm32之watchdog
在嵌入式系统中,由于MCU的工作常常受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统陷入停滞状态,发送不可预料的后果,所以出 ...
- c++构造析构顺序
class A { public: A(){ cout << "constrcut A" << endl; }; ~A(){ cout << & ...