[HNOI2004][bzoj1212] L语言 [Trie+dp]
题面
思路
无后效性
显然,不管某个前缀的理解方式是怎么样的,如果它能被理解,那么前面的决策对于后面的决策而言都是等价的
因此这题可以DP
DP方程
令$dp[i]$表示前缀i是否能被理解
那么,显然状态转移方程为:
$dp[i]=dp[i]||dp[j];;(s[j+1...i]\in D)$
也就是说,现在我们的问题转化为:求第i位往前数可以匹配的所有单词
因为这个往前数的方向和方式是唯一的,所以我们想到一个字符串数据结构:$Trie$
$Trie$
一个非常常规的想法,就是把所有单词插到$trie$里面,然后用这个往前数的子串去匹配单词
但是这样有一个问题:我们是从$trie$的某一个深层次位置往根匹配,而这样的开始节点可能有多个
这个问题出现的根本原因,是因为我们是拿一个后缀去匹配单词的,但是我们的$trie$以前缀方式保存
所以,我们只要把$trie$保存的方式从前缀变成后缀就好了
我们把所有单词反向,插入$trie$里面
求$dp[i]$的时候,从$s[i]$开始往前,$trie$从根节点开始,向下走,走到一个单词的结尾(实际上反过来以后就是单词的开头),就用这个位置更新$dp[i]$
总时间效率上限:
$O\left(m\left(10strlen(s)+O\left(Trie\right)\right)\right)=O\left(2\ast10^8\right)$
但是一般达不到这么多,我的代码最后一个点272ms,还是很稳的
实在不行,给评测机吸氧啊【雾】
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{//trie节点
int num,son[27];
node(){num=0;memset(son,0,sizeof(son));}
}x[210];
int n,m,dp[1000010],cnt;char a[1000010];
void add(char s[20]){//插入单词
int len=strlen(s),cur=0,i;
for(i=len-1;i>=0;i--){
if(!x[cur].son[s[i]-'a']) x[cur].son[s[i]-'a']=++cnt;
cur=x[cur].son[s[i]-'a'];
}
x[cur].num++;
}
void check(char s[],int pos){
int cur=0,i,flag=0;
for(i=pos-1;i>=0;i--){
if(!x[cur].son[s[i]-'a']) break;
cur=x[cur].son[s[i]-'a'];if(x[cur].num&&dp[i]) flag=1;
}
dp[pos]=flag;
}
int main(){
scanf("%d%d",&n,&m);int i,len,l,j,ans;char s[20];
for(i=1;i<=n;i++) scanf("%s",s),add(s);
for(l=1;l<=m;l++){
scanf("%s",a);memset(dp,0,sizeof(dp));
dp[0]=1;len=strlen(a);ans=0;
for(i=1;i<=len;i++){
check(a,i);
if(dp[i]) ans=max(i,ans);
}
printf("%d\n",ans);
}
}
[HNOI2004][bzoj1212] L语言 [Trie+dp]的更多相关文章
- Luogu P2292 [HNOI2004]L语言(Trie+dp)
P2292 [HNOI2004]L语言 题面 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章 \(T\) 是由若干小写字母构成. ...
- 洛谷.2292.[HNOI2004]L语言(Trie DP)
题目链接 /* 简单的DP,查找是否有字典中的单词时在Trie树上做 要注意在最初Match(0)一遍后,i还是要从0开始匹配,因为如果有长度为1的单词,Match(i+1)不会从1更新 1M=102 ...
- [HNOI2004]Language L语言
2777: [HNOI2004]Language L语言 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 10 Solved: 5[Submit][S ...
- 【BZOJ1212】[HNOI2004]L语言 Trie树
[BZOJ1212][HNOI2004]L语言 Description 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构 ...
- 洛谷:P2292 [HNOI2004]L语言(DP+Trie树)
P2292 [HNOI2004]L语言 题目链接:https://www.luogu.org/problemnew/show/P2292 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有 ...
- BZOJ1212[HNOI2004]L语言——trie树+DP
题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...
- BZOJ1212: [HNOI2004]L语言(Trie图+DP)
Description 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D ...
- [HNOI2004]L语言 trie树? Ac自动机? hash!!
题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...
- BZOJ 1212: [HNOI2004]L语言 trie
长度小于 10 是关键信息~ #include <cstdio> #include <cstring> #include <algorithm> #define N ...
随机推荐
- gearmand 编译 Unable to find libevent
如果出现configure: error: Unable to find libevent,则输入命令:yum -y install libevent libevent-devel然后重新config ...
- Java不同对象之间复制属性
// 导入包import org.springframework.beans.BeanUtils; /** * 调用工具复制2个对象之间的属性 2个JavaBean对象复制的属性名相同 * @para ...
- c++ 软件下载 Dev cpp下载
下载地址: 链接: https://pan.baidu.com/s/1hsiWQPY 密码: bdpn
- API调用微信getWXACodeUnlimit()获取小程序码
微信文档地址:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/qr-code/getWXACodeUnlimit.html? ...
- oracle 多行数据合并一行数据
在工作中遇见的oracle知识,多行合并成一行,记录一下 1.取出需要的数据,代码: (SELECT to_char(m.f_meetdate, 'yyyy-MM-dd'), decode(nvl(m ...
- linux下避免僵尸进程的几种方法
linux下我们可以调用fork函数创建子进程,创建的子进程将会得到父进程的数据空间.堆.栈......副本(采用写时复制机制),子进程将会继承父进程的信号掩码.信号处理方式.当前工作目录.会话id. ...
- 微信小游戏 demo 飞机大战 代码分析 (二)(databus.js)
微信小游戏 demo 飞机大战 代码分析(二)(databus.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞机大战 代码分析(三)(spirit. ...
- SSH密钥验证
基于密钥验证 1. 在客户端生成密钥对 可以先进入用户的.ssh 目录 cd ~/.ssh ssh-keygen -t rsa [-P '' ] [-f "~/.ssh/id_rsa&quo ...
- NopCommerce(Core)学习目录
1.NopCommerce下载运行 2.登录及权限 3.日志 4.依赖注入使用autofac 5.插件实现 ...
- PHP array_multisort()函数超详细理解
项目中用到这个函数了 ,起初对这个函数一直是懵逼状态,文档都看的朦朦胧胧的 网上无意间看到这篇文章 ,写的超级详细,收藏了 . 当然要先放原地址:https://www.cnblogs.com/WuN ...