题意:白书P209

本题用普通字典树会更快,为了练习还是尝试再敲一遍左儿子-右兄弟字典树(其实就是字典树上开前向星)

dp[i]为满足[i...len)的分配方案数,转移方程为dp[i]=sum{dp[i+slen(j)],如果后缀j存在符合前缀的方案,slen(j)为该后缀完全匹配前缀的长度}

这种利用前缀进行dp从后往前推的方法我并没有用过,学习了

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int MAXN = 2e6+11;
const int MOD = 20071027;
char str[MAXN>>1],s[MAXN>>1];
int dp[MAXN>>1];
struct Trie{
int son[MAXN],bro[MAXN],tot,root;
char val[MAXN];
int sz[MAXN];
int isword[MAXN];
void init(){
memset(son,-1,sizeof son);
root=0;tot=1;
val[root]=0;sz[root]=0;isword[root]=0;
}
int node(int fa,char ch){
bro[tot]=son[fa]; son[fa]=tot;//yuanlaide diyige zuoerzi bianwei youxiongdi
val[tot]=ch; sz[tot]=0; isword[tot]=0; // son[tot]=-1;
return tot++;
}
void insert(char str[]){
int now=0,lc=-1;
for(int i=0;str[i];i++){
bool flag=0;
for(lc=son[now];~lc;lc=bro[lc]){
if(val[lc]==str[i]){
flag=1;break;
}
}
if(!flag) lc=node(now,str[i]);
now=lc;sz[now]++;
}
isword[now]++;
}
int find(int from,int to){
int now=0,lc=-1,ans=0;
for(int i=from;i<to;i++){
bool flag=0;
for(lc=son[now];~lc;lc=bro[lc]){
if(val[lc]==str[i]){
flag=1;
if(isword[lc]) ans=(ans+dp[i+1])%MOD;
now=lc;
break;
}
}
if(!flag) break;
}
return ans;
}
}trie;
int main(){
int kase=0;
while(~scanf("%s",str)){
trie.init();
int n; scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s);
trie.insert(s);
}
int len=strlen(str);
memset(dp,0,sizeof dp);
dp[len]=1;//!!!
for(int i=len-1;i>=0;i--){
int tmp=trie.find(i,len);
dp[i]=tmp;
}
printf("Case %d: %d\n",++kase,dp[0]);
}
return 0;
}

UVALive - 3942 左儿子trie DP的更多相关文章

  1. UVALive - 3942 Remember the Word[Trie DP]

    UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...

  2. UVALive 3942 Remember the Word 字典树+dp

    /** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5) ...

  3. UVa 11732 "strcmp()" Anyone? (左儿子右兄弟前缀树Trie)

    题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php? ...

  4. 左儿子右兄弟Trie UVA 11732 strcmp() Anyone?

    题目地址: option=com_onlinejudge&Itemid=8&category=117&page=show_problem&problem=2832&qu ...

  5. UVA 3942 Remember the Word (Trie+DP)题解

    思路: 大白里Trie的例题,开篇就是一句很容易推出....orz 这里需要Trie+DP解决. 仔细想想我们可以得到dp[i]=sum(dp[i+len[x]]). 这里需要解释一下:dp是从最后一 ...

  6. 【暑假】[实用数据结构]UVAlive 3942 Remember the Word

    UVAlive 3942 Remember the Word 题目: Remember the Word   Time Limit: 3000MS   Memory Limit: Unknown   ...

  7. Vijos p1518 河流 转二叉树左儿子又兄弟

    左儿子又兄弟的转发一定要掌握啊,竞赛必用,主要是降低编程复杂度,省时间.个人觉得状压DP也是为了降低编程复杂度. 方程就不说了,程序应该能看得懂,用的记忆化搜索,方便理解. #include<c ...

  8. UVALive - 3942 Remember the Word[树状数组]

    UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...

  9. Remember the Word UVALive - 3942(dp+trie)

    题意: 给S个不同的单词和一个长字符串 问将其分解为若干个单词有多少种方法(单词可重复使用) 解析: dp[i]表示在这个字符串中以某个位置i为起点的 的一段子字符串 则这个子字符串若存在某个前缀恰好 ...

随机推荐

  1. php_imagick超强的PHP图片处理扩展

      php_imagick是一个可以供PHP调用ImageMagick功能的PHP扩展,使用这个扩展可以使PHP具备和ImageMagick相同的功能. ImageMagick是一套功能强大.稳定而且 ...

  2. 453D Little Pony and Elements of Harmony

    传送门 分析 我们可以将所有的b[i^j]直接对应到b[f(i^j)]上 于是显然可以fwt 我们对b进行t次fwt之后直接将答案与e0卷起来即可 注意由于模数不确定,我们可以将模数扩大$2^m$然后 ...

  3. jquery表单数据反序列化为字典

    .前台代码 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1 ...

  4. oracle plsql参数

    declare inst_name varchar2(100); cursor mycur is select * from tran_forward t where t.instrument_typ ...

  5. 第二章启程前的认知准备,2.1Opencv官方例程引导与赏析

    1.在opencv安装目录下,可以找到opencv官方提供的示例代码,具体位于...\opencv\sources\samples目录下,如下所示 名为c的文件夹存放着opencv1.0等旧版本的示例 ...

  6. bug记录:IE8,包含块min-height/height共存时的高度计算bug

    问题的条件有: A元素是B元素的包含块. A元素设置overflow:hidden;,并同时设置了height和min-height,同时height计算值 < min-height 原生IE8 ...

  7. TensorFlow安装教程

    Windows7 安装TensorFlow(本人试了好多方法后的成果):https://www.cnblogs.com/bxyan/p/6869237.html Linux: sudo pip ins ...

  8. 编写高质量代码改善C#程序的157个建议——建议53:必要时应将不再使用的对象引用赋值为null

    建议53:必要时应将不再使用的对象引用赋值为null 在CLR托管的应用程序中,存在一个“根”的概念,类型的静态字段.方法参数.以及局部变量都可以作为“根”的存在(值类型不能作为“根”,只有引用类型的 ...

  9. Socket编程(c语言示例)

    转自:http://blog.csdn.net/dxpqxb/article/details/8166423 前言 Socket可以看成在两个程序进行通讯连接中的一个端点,是连接应用程序和网络驱动程序 ...

  10. window7 Oracle卸载步骤

    完全卸载oracle11g步骤:1. 开始->设置->控制面板->管理工具->服务(或 运行 services.msc) 停止所有Oracle服务.2. 开始->程序-& ...