第一道\(AC\)自动机\(+DP.\)

首先,一个自动机上\(DP\)的套路是设\(dp[i][j]\)表示长度为\(i\)匹配到\(j\)节点的最优得分。

那么,由于我们已经建好了\(Trie\)图,我们就应该提前把走到节点\(j\)的所有连击操作处理出来。

有一条显然结论:如果在\(fail\)树上经过了这个串结尾节点中子树中的任意一点,则这次匹配一定会包含这个串。

换句话说,我们在对每一个节点更新\(fail\)的时候,其分值应该直接把其\(fail\)的分值加上。

于是我们进行\(dp.\)

首先初始值都是\(-inf,\)但对于匹配节点在根的情况应该是\(0.\)

至于为什么\(dp[0][*]\)不能赋值为\(0,\)是因为根本不可能存在这种状态。匹配长度为\(0\)不可能匹配到其他节点。

但初始时,不管哪一个节点和\(0\)匹配,其一定不会有任何分数。根节点本身是一个空节点。

解决初始值问题,我们可以进行\(dp.\)

枚举长度,枚举节点,再枚举字符。对于一个状态,我们应该取所有能到达这个状态的\(dp\)值的\(\max.\)因为我只能输入\(k\)个字符。

剩下的就是模板了。

#include<bits/stdc++.h>
using namespace std;
int dp[5000][2000];
const int MAXN=4000;
int pos[MAXN],cnt[MAXN];
int tot,n;
char st[MAXN];
struct Tree{
int ch[3],fail;
}T[MAXN];
vector<int>to[MAXN];
int num[MAXN];
int insert(char *str,int len){
int u=0;
for(int i=0;i<len;++i){
int x=str[i]-'A';
if(!T[u].ch[x])T[u].ch[x]=++tot;
u=T[u].ch[x];
}
num[u]++;return u;
}
void bfs(){
queue<int>q;
for(int i=0;i<3;++i){
if(T[0].ch[i]){
int v=T[0].ch[i];
T[v].fail=0;
q.push(v);
}
}
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<3;++i){
if(T[u].ch[i]){
int v=T[u].ch[i];
T[v].fail=T[T[u].fail].ch[i];
q.push(v);
}
else T[u].ch[i]=T[T[u].fail].ch[i];
}
to[T[u].fail].push_back(u);
num[u]+=num[T[u].fail];
}
}
int K; int main(){
scanf("%d%d",&n,&K);
for(int i=1;i<=n;++i){
scanf("%s",st);
int L=strlen(st);
pos[i]=insert(st,L);
}
bfs();
memset(dp,128,sizeof(dp));
for(int i=0;i<=K;++i)dp[i][0]=0;
for(int i=1;i<=K;++i){
for(int j=0;j<=tot;++j){
for(int k=0;k<3;++k){
dp[i][T[j].ch[k]]=max(dp[i][T[j].ch[k]],dp[i-1][j]+num[T[j].ch[k]]);
}
}
}
int ans=0;
for(int i=0;i<=tot;++i)ans=max(ans,dp[K][i]);
printf("%d\n",ans);
return 0;
}

【题解】[USACO12JAN]Video Game G的更多相关文章

  1. 落谷P3041 [USACO12JAN]Video Game G

    题目链接 多模式匹配问题,先建 AC 自动机. 套路性的搞个 DP: \(f[i][j]\) 表示前 \(i\) 个字符,当前在 \(AC\) 自动机上的节点是 \(j\) 能匹配到的最多分. 初始化 ...

  2. ACM ICPC 2018 青岛赛区 部分金牌题题解(K,L,I,G)

     目录: K Airdrop I Soldier Game L Sub-cycle Graph G Repair the Artwork ———————————————————— ps:楼主脑残有点严 ...

  3. 洛谷 P3041 [USACO12JAN] Video Game Combos

    题目描述 Bessie is playing a video game! In the game, the three letters 'A', 'B', and 'C' are the only v ...

  4. [USACO12JAN]Video Game Combos

    AC自动机建立fail树后树上DP # include <stdio.h> # include <stdlib.h> # include <iostream> # ...

  5. 【题解】[USACO07OPEN]Dining G

    \(Link\) \(\text{Solution:}\) 这一题,我们要做到,食物和牛.牛和饮料均为一对一的关系.我们发现这个图不好建立. 经典技巧:将牛拆边,拆成入点和出点,并连容量为\(1\)的 ...

  6. 【题解】[USACO07NOV]Sunscreen G

    \(Link\) \(\text{Solution:}\) 把奶牛的忍耐度转化为线段,则题目转化为选择一些点使得覆盖的线段尽可能多.一个点只能覆盖一条线段. 考虑将点按照位置排序,线段按照右端点排序. ...

  7. [题解] [USACO05JAN]Muddy Fields G

    题目TP门 题目大意 在一个 \(R×C\) 的矩阵中,每个点有两个状态:草地和泥地.你需要在泥地里铺 \(1×k\) 木块, \(k\) 为任意整数,求最少要多少木块. 思路 两个横向木块不会互相干 ...

  8. AC 自动机学习笔记

    虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...

  9. 【BZOJ】2277: [Poi2011]Strongbox

    题意 有一个密码箱,\(0\)到\(n-1\)中的某些整数是它的密码.如果\(a\)和\(b\)都是它的密码,那么\((a+b)%n\)也是它的密码(\(a,b\)可以相等).某人试了\(k\)次密码 ...

随机推荐

  1. SQL SERVER管理维护计划错误,备份错误,1053/3041/错误18204,严重性16,状态1

    在sqlserv2008/2012里设置了管理-维护计划-备份计划,前些天遇到报错-1053/3041/错误18204,严重性16,状态1等:分享下解决方法. 1.在服务器执行任务报错 2.解决办法 ...

  2. Zookeeper原生客户端

    1.1.1.1. 客户端基本操作 package cn.enjoy.javaapi; import org.apache.zookeeper.*; import java.io.IOException ...

  3. 基于jQuery的鼠标悬停时放大图片的效果制作

    这是一个基于jQuery的效果,当鼠标在小图片上悬停时,会弹出一个大图,该大图会跟随鼠标的移动而移动.这个效果最初源于小敏同志的一个想法,刚开始做的时候只能实现弹出的图片是固定的,不能随鼠标移动,最后 ...

  4. 居然仅用浏览器,就完成了Spring Boot应用的开发与部署!

    最近有幸试用了一下阿里云的一个新产品:云开发平台,体验一把全新的开发模式!虽然中间也碰到了一些问题,但整体的体验透露着未来感,因为整个过程都不需要使用我们最常用的IDEA,仅依靠浏览器就把一个Spri ...

  5. Linux rndis_host 驱动的一个BUG与解决方案

    关键字 rndis_host, linux, kernel, modem 综述 rndis 是微软定义的一套通讯方案.类似的协议还有 qmi/mbim/ecm/ncm. rndis 协议足够简单,可靠 ...

  6. element ui 分页记忆checked

    <el-table :data="tableData" border ref="multipleTableChannel" @selection-chan ...

  7. Linux实战(18):Centos强制踢掉某登录用户的方法

    [root@localhost ~]# pkill -kill -t pts/2

  8. 文档驱动 —— 表单组件(五):基于Ant Design Vue 的表单控件的demo,再也不需要写代码了。

    源码 https://github.com/naturefwvue/nf-vue3-ant 特点 只需要更改meta,既可以切换表单 可以统一修改样式,统一升级,以最小的代价,应对UI的升级.切换,应 ...

  9. Boolean.valueOf(String)

    Boolean.valueOf(String) a. 当 String 的参数值在不区分大小写的时候等于 "true" ,则 Boolean.valueOf(String) 返回值 ...

  10. Flutter学习四之实现一个支持刷新加载的列表

    上一篇文章用Scaffold widget搭建了一个带底部导航栏的的项目架构,这篇文章就来介绍一下在flutter中怎么实现一个带下拉刷新和上拉加载更多的一个列表,这里用到了pull_to_refre ...