[USACO12Jan][luogu3041] Video Game Combos [AC自动机+dp]
题面
思路
首先,有一个非常显然的思路就是dp:
设$dp[i][j]$表示前i个字符,最后一个为j
然后发现这个东西有后效性
改!设$dp[i][j]$代表前i个字符,最后15个的状态为j(压缩一下),转移的是候枚举增加那个字符,然后看从谁可以推过来
然后就TLE了,完全无压力
怎么优化这个算法?
显然,枚举完增加哪个字符以后,可以用AC自动机来实现多模匹配
然后发现:我们把j的定义变成AC自动机上面的点j,这样一个点就代表一种状态,状态之间互相不重复,而且也没有后效性
这样的定义方法还有一个好处:状态少,从$3^{15}$个变成了$300$个
于是我们得到最终做法:
最终算法
对于输入的模板串建立AC自动机
令$dp[i][j]$表示前i个字符,最后一个字符跑到AC自动机的第j位上的最大答案
于是我们只要对于每个$dp[i][j]$枚举下一个是A,B,C,转移到下一个节点j',然后跳一遍fail指针
对于匹配到的一个长度为k的模板串,$dp[i+1][j']=max\left(dp[i+1][j'],dp[i-k][j]\right)$
最后答案就是$dp[K][i]$的最大值
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node{
int num,fail,son[3];
node(){num=fail=0;memset(son,0,sizeof(son));}
}a[510];int cnt;
void add(char s[]){//插入字符串到trie
int len=strlen(s),i,cur=0;
for(i=0;i<len;i++){
if(!a[cur].son[s[i]-'A']) a[cur].son[s[i]-'A']=++cnt;
cur=a[cur].son[s[i]-'A'];
}
a[cur].num++;
}
void getfail(){//bfs求fail指针
int u,v,q[510],head=0,tail=0,i;
for(i=0;i<3;i++){
if(!a[0].son[i]) continue;
a[0].fail=0;q[tail++]=a[0].son[i];
}
while(head<tail){
u=q[head++];
for(i=0;i<3;i++){
v=a[u].son[i];
if(v) a[v].fail=a[a[u].fail].son[i],q[tail++]=v;
else a[u].son[i]=a[a[u].fail].son[i];
}
}
}
int m,n,dp[1010][510];bool vis[1010][510];
int proc(int cur,int val){//跳fail指针求值
while(cur) val+=a[cur].num,cur=a[cur].fail;
return val;
}
int main(){
scanf("%d%d",&m,&n);int i,j,k,tmp;char s[20];
for(i=1;i<=m;i++) scanf("%s",s),add(s);
getfail();vis[0][0]=1;
for(i=0;i<n;i++){
for(j=0;j<=cnt;j++){
if(!vis[i][j]) continue;
for(k=0;k<3;k++){
tmp=a[j].son[k];
dp[i+1][tmp]=max(dp[i+1][tmp],proc(tmp,dp[i][j]));
vis[i+1][tmp]=1;
}
}
}
int ans=0;
for(i=0;i<=cnt;i++) ans=max(ans,dp[n][i]);
printf("%d\n",ans);
}
[USACO12Jan][luogu3041] Video Game Combos [AC自动机+dp]的更多相关文章
- [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机+DP)
Description 贝西正在打格斗游戏.游戏里只有三个按键,分别是“A”.“B”和“C”.游戏中有 N 种连击 模式,第 i 种连击模式以字符串 Si 表示,只要贝西的按键中出现了这个字符串,就算 ...
- 洛谷P3041 视频游戏的连击Video Game Combos [USACO12JAN] AC自动机+dp
正解:AC自动机+dp 解题报告: 传送门! 算是个比较套路的AC自动机+dp趴,,, 显然就普普通通地设状态,普普通通地转移,大概就f[i][j]:长度为i匹配到j 唯一注意的是,要加上所有子串的贡 ...
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 2457(ac自动机+dp)
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2296——Ring(AC自动机+DP)
题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...
随机推荐
- 2018.6.4 Oracle数据库预定义的异常列表
declare v_ename emp.ename%type; begin select ename into v_ename from emp where empno=&gno; dbms_ ...
- 基础I/O
基础IO: c库文件IO操作接口:(详细查看c语言中的文件操作函数总结:https://www.cnblogs.com/cuckoo-/p/10560640.html) fopen 打开文件 fclo ...
- C# 创建和初始化集合对象
一. 引言 C# 3.0中新的对象初始化器是一种简单的语法特征-借助于这种特征,对象的构建和初始化变得非常简单.假定你有一个类Student,它看起来有如下样子: public class Stude ...
- WinSCP使用与linux命令(小部分命令)
一.下载一个WinSCP WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端.同时支持SCP协议.它的主要功能就是在本地与远程计算机间安全的复制文件..winscp也可以链接其 ...
- Oracle 事务 锁
一. 事务 是一系列的数据库操作,是数据库应用的基本逻辑单位以及并发控制的基本单位.所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位. 要将有组语句作为事务考 ...
- Vue中结合clipboard实现复制功能
首先现在Vue中引入clipboard npm install clipboard --save 在需要使用的组件中import 引入clipboard import Clipboard from ' ...
- 微信小程序text标签
最近在做小程序,使用<text>标签的时候发现里面的文本text-family不生效, 经过试验,发现直接在text标签的class设置不生效,可以在外层包一个父元素就可以设置了. < ...
- 2018.10.30 NOIp模拟赛T2 数字对
[题目描述] 小 H 是个善于思考的学生,现在她又在思考一个有关序列的问题. 她的面前浮现出一个长度为 n 的序列{ai},她想找出一段区间[L, R](1 <= L <= ...
- Java - Java 中的三种 ClassLoader
1.虚拟机类加载器(称为“bootstrap class loader”),它本身没有父类加载器,它负责加载虚拟机的内置类,由于它是用C.C++写的,所以Java无法拿到其class文件,返回的都是空 ...
- aop配置问题引发的报错
今天在使用注解配置aop时出现了几次的错误 INFO - Refreshing org.springframework.context.support.ClassPathXmlApplicationC ...