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+ ...
随机推荐
- c++ 实现将数字转换为中文数字输出
实现如下函数: void printInChinese(int num); 这个函数输入一个小于100000000(一亿)的正整数,并在屏幕上打印这个数字的中文写法. 例如: 17 -> 一十七 ...
- Oracle Database 12c Release 1 Installation On Oracle Linux 6.4 x86_64
Create groups and users [root@vmdb12c ~]# groupadd oinstall [root@vmdb12c ~]# groupadd dba [root@vmd ...
- css网页自适应-2
昨天中午Google进行了一次在线讲座,讲述自适应网页设计的概念和方法,维护同一个网页代码,即可使网站在多种浏览设备(从桌面电脑显示器到智能手机或其他移动产品设备)上具有更好的阅读体验,这里我将该讲座 ...
- CPU指令的流水线运行
指令集是CPU体系架构的重要组成部分.C语言的语法是对解决现实问题的运算和流程的方法的高度概况和抽象,其主要为算术.逻辑运算和分支控制,而指令集就是对这些抽象的详细支持,汇编仅仅只是是为了让开发者更好 ...
- centos安装vim7.4
转载于:http://www.cnblogs.com/nhlinkin/p/3545509.html 系统版本centos6.4; root权限 su - root 卸载 $ rpm - ...
- PHP - 目录、文件操作
目录操作: <?php /** * Read Directory. * Just read the top-level directory. * @param string $path dire ...
- python学习(一)
1 python一切皆为对象,因为现实 包含了一系列的数据和操作这些数据的方法的一个整体,就叫作对象. 自行车 属性:手刹车,轮胎,脚踏板方法:如何前进的方法,控制停止的方法,控制方向 实际内容 男人 ...
- iOS7,8 presentViewController 执行慢
解决办法: 1, 使用GCD用主线程跳转 dispatch_async(dispatch_get_main_queue(), ^{ //跳转代码 ... }); 2, 召唤主线程, 使用perform ...
- windows和centos用cutycapt截网页的图
centos下:(主要参考http://loosky.net/2816.html) (1)安装qt47 增加qt47的源 vim /etc/yum.repos.d/atrpms.repo //加入如下 ...
- C语言循环剖析(转载)
一.if.else float变量与“零值”进行比较: float fTestVal = 0.0; if((fTestVal >= -EPSINON) && (fTestVal ...