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++:从子类访问父类的私有函数
众所周知,c和c++的数组都是不安全的,因为无论c还是c++都不提供数组边界检查功能,这使得数组溢出成为可能.从某个意义上说,c和c++是一种缺少监督的语言,然而这也正是其魅力所在.c++给予程序员更 ...
- 国外稳定的免费PHP空间byethost.com
byethost.com是一个老牌的免费空间商,从2006年起就開始提供免费空间了,其免费服务很稳定(看完下文你就知道有多稳定了). 提供5.5G的免费空间,200G的月流量,能够绑定50个域名,也能 ...
- 关于FTP操作的功能类
自己在用的FTP类,实现了检查FTP链接以及返回FTP没有反应的情况. public delegate void ShowError(string content, string title); // ...
- BZOJ 3275: Number( 最小割 )
S->每个奇数,每个偶数->T各连一条边, 容量为这个数字.然后不能同时选的两个数连容量为+oo的边. 总数-最大流即是答案. 因为满足a2+b2=c2的a,b一定是一奇一偶或者两个偶数, ...
- js 中的cookie
根据智能社31cookie基础与应用总结, cookie的特性: 1.同一个网站,共用一套cookie,实际上是根据域名来区分的. 如t.sina.com.cn ,和weibo.com这两个都是新浪微 ...
- jQuery中的index方法介绍
从jq api手册摘过来的内容,index这个方法在写 tab silder 之类的组件还是比较有用的说. js没有传统的函数重载的概念,但是根据传入参数的不同,js的函数可以完成不同的功能,也可说是 ...
- 17.1.1.4 Obtaining the Replication Master Binary Log Coordinates 获取复制Master Binary Log的坐标:
17.1.1.4 Obtaining the Replication Master Binary Log Coordinates 获取复制Master Binary Log的坐标: 你需要master ...
- 基于visual Studio2013解决算法导论之030二叉查找树
题目 二叉查找树 解决代码及点评 // 12二叉查找树.cpp : 定义控制台应用程序的入口点. // // 3 - 10二叉搜索树查找.cpp : 定义控制台应用程序的入口点. // #in ...
- 基于visual Studio2013解决算法导论之020单链表
题目 单链表操作 解决代码及点评 #include <iostream> using namespace std; struct LinkNode { public: LinkNo ...
- 使用 stvd 编译STM8S 时能看到使用RAM ROM大小的方法
刚刚安装的STVD编译器,编译时候不显示用了多少RAM和ROM?对于此问题.有两个方法:一是看.map文件 还有一种是 添加一个补丁,详细操作例如以下,能够在我的资源里下载对应的文件. http:// ...