第一道\(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. Android开发工程师面试题之handler详解。android程序员,android开发面试资料,详解

    Message:消息:其中包含了消息ID,消息对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理 Handler:处理者:负责Message发送消息及处理.Handler ...

  2. fragment没有getWindowManager 关于fragment下的报错解决方法

    其实很简单:只需要在getWindowManager().getDefaultDisplay().getMetrics(metric) 前面加上getactivity()即可.

  3. C#委托链

    使用Delegate.Combine时,注意两点: 1. 不可以将不同签名的两个委托相互Combine. 2.如果将有返回值的两个委托A 和 B Combine,那么返回值是最后一个委托的的返回值,也 ...

  4. 这应该是最适合国内用户的K3s HA方案

    前 言 在面向生产环境的实践中,高可用是我们无法避免的问题,K3s本身也历经多个版本的迭代,HA方案也进行了不断优化,形成了目前的比较稳定的HA方案. 目前官方提供两种HA方案: 嵌入式DB的高可用( ...

  5. Sequence (矩阵快速幂+快速幂+费马小定理)

            Holion August will eat every thing he has found. Now there are many foods,but he does not wa ...

  6. NutUI 视频组件开发心得

    引子 说到在项目中引入一个视频,我们肯定会想到 HTML5 为我们提供的 Video 标签,它为我们提供了许多属性和方法,使用起来很方便,当然直接使用也会遇到各种兼容问题,在最初学习 Video 标签 ...

  7. TP6.0 获取请求对象的五种方式

    目录 1. 门面类 2. 依赖注入 3. 框架提供的基础控制器的 request 属性 4. request() 助手函数 5. app() 超级助手函数 think\Request.think\fa ...

  8. python基础:多进程、多线程

    一.定义和区别 1.一个任务就是一个进程,进程就是资源的集合.比如打开浏览器,启动一个进程.当一个进程需要干很多事的时候,就需要执行多个子任务,这些子任务就是线程. 2.线程是包含在进程中的,每个进程 ...

  9. java中包名命名规范

    在idea中创建package遇到的问题 发现一个问题,当我创建一个lesson-02的package时,输入这个包名后,package自动变成了文件夹 在网上搜索发下java包名一般是小写字母进行命 ...

  10. selenium常用api之切换:table切换、alert弹框切换、iframe框架切换

    10.查看浏览器打开了多少个table和当前页面在哪个table 测试:打开了浏览器后,打开了一个新的标签页之后,显示此时有2个table,浏览器中当前页面展示的是第2个页面,但是代码打印显示的仍然是 ...