[bzoj1212][HNOI2004]L语言_AC自动机_动态规划
2024-08-31 07:07:22
L语言 bzoj-1212 HNOI-2004
题目大意:给你一个n个单词的集合,然后给你m条字符串。问每条字符串可以被理解的最长前缀。被理解当且仅当存在一种分割使得每一段都是集合里的元素。
注释:$1\le n,m\le 20$,长度不超过1M
想法:做了上一道,感觉这是个大水题... ...,我们将那个单词集合建立一个AC自动机,然后将每一个询问的字符串仍在字符串上跑,用bool型的dp。
dp[i]表示当前字符串前i位是否能被理解。
转移:如果j+1到i这段能被理解,那么dp[i]|=dp[j];
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 2000010
using namespace std;
char s[N];
int a[300][26];
bool end[300];
int n,m,cnt,fail[300],f[N];
void build(char *s)
{
int now=0;
int len=strlen(s);
for(int i=0;i<len;i++)
{
if(!a[now][s[i]-'a'])
{
a[now][s[i]-'a']=++cnt;
}
now=a[now][s[i]-'a'];
}
end[now]=true;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
build(s);
}
while(m--)
{
scanf("%s",s);
int l=strlen(s);
memset(f,0,sizeof f);
f[0]=1;
for(int i=0;i<l;i++)
{
if(f[i])
{
int now=0;
for(int j=i;a[now][s[j]-'a'];j++)
{
now=a[now][s[j]-'a'];
if(end[now])
{
f[j+1]|=f[i];
}
}
}
}
for(int i=l;~i;i--)
{
if(!f[i]) continue;
printf("%d\n",i);
break;
}
}
}
小结:ac自动接其实可以当Trie使.. ...虽然我写这东西是Trie图..
最新文章
- Java消息队列--ActiveMq 实战
- Java的垃圾回收和内存分配策略
- (一)Maven初步了解与认识
- 解剖SQLSERVER 第六篇 对OrcaMDF的系统测试里避免regressions(译)
- Nginx 配置详解
- 【转】Apache Options Indexes FollowSymLinks详解
- 在Linux里读取UBOOT环境变量
- (3)java棧
- SQLServer加入域后无法远程连接
- Code Snippet Library
- pcduino通过sd卡刷系统
- centos安装Chromium
- 在64位Win7操作系统中安装Microsoft Access Engine的解决方案
- codeforces 591B Rebranding (模拟)
- 使用Spring时web.xml中的配置
- OpenGL开发学习指南二(glfw+glad)
- boke练习: springboot整合springSecurity出现的问题,传递csrf
- jvm加载类(更新中)
- ALGO-139_蓝桥杯_算法训练_s01串(递归)
- phpunit 生成三种日志文件的配置方法