题目链接


多模式匹配问题,先建 AC 自动机。

套路性的搞个 DP:

  • \(f[i][j]\) 表示前 \(i\) 个字符,当前在 \(AC\) 自动机上的节点是 \(j\) 能匹配到的最多分。
  • 初始化 \(f[0][0] = 0\),其余为负无穷
  • 答案 \(\max\{f[K][i]\}\)

考虑一条边 \(u \Rightarrow v\),加入后缀的贡献,即 \(f[i][v] = \max(f[i - 1][u] + val(v))\)

其中 \(val(v)\) 表示 \(v\) 这个点上出现的模式串个数,即其 fail 树的他到根的链上的是模式串末尾的个数。

复杂度 \(O(45NK)\)。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; const int S = 20, L = 305, M = 1005; int n, K, tr[L][3], fail[L];
int cnt[L], q[L], idx, f[M][L];
char s[S]; void insert() {
int p = 0;
for (int i = 1; s[i]; i++) {
int ch = s[i] - 'A';
if (!tr[p][ch]) tr[p][ch] = ++idx;
p = tr[p][ch];
}
cnt[p]++;
} void build() {
int hh = 0, tt = -1;
for (int i = 0; i < 3; i++)
if (tr[0][i]) q[++tt] = tr[0][i];
while (hh <= tt) {
int u = q[hh++];
for (int i = 0; i < 3; i++) {
int v = tr[u][i];
if (v) {
fail[v] = tr[fail[u]][i];
cnt[v] += cnt[fail[v]];
q[++tt] = v;
} else tr[u][i] = tr[fail[u]][i];
}
}
} int main() {
memset(f, 0xcf, sizeof f);
scanf("%d%d", &n, &K);
for (int i = 1; i <= n; i++) {
scanf("%s", s + 1);
insert();
}
build();
f[0][0] = 0;
for (int i = 0; i < K; i++) {
for (int u = 0; u <= idx; u++) {
if (f[i][u] < 0) continue;
for (int j = 0; j < 3; j++) {
int v = tr[u][j];
f[i + 1][v] = max(f[i + 1][v], f[i][u] + cnt[v]);
}
}
}
int ans = 0;
for (int i = 0; i <= idx; i++) ans = max(ans, f[K][i]);
printf("%d\n", ans);
}

落谷P3041 [USACO12JAN]Video Game G的更多相关文章

  1. 洛谷 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 ...

  2. 【题解】[USACO12JAN]Video Game G

    第一道\(AC\)自动机\(+DP.\) 首先,一个自动机上\(DP\)的套路是设\(dp[i][j]\)表示长度为\(i\)匹配到\(j\)节点的最优得分. 那么,由于我们已经建好了\(Trie\) ...

  3. 洛谷P3041 视频游戏的连击Video Game Combos [USACO12JAN] AC自动机+dp

    正解:AC自动机+dp 解题报告: 传送门! 算是个比较套路的AC自动机+dp趴,,, 显然就普普通通地设状态,普普通通地转移,大概就f[i][j]:长度为i匹配到j 唯一注意的是,要加上所有子串的贡 ...

  4. 【洛谷 P3041】 [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机,dp)

    题目链接 手写一下AC自动机(我可没说我之前不是手写的) Trie上dp,每个点的贡献加上所有是他后缀的串的贡献,也就是这个点到根的fail链的和. #include <cstdio> # ...

  5. P3041 [USACO12JAN]视频游戏的连击Video Game Combos

    思路 简单的AC自动机上dp,暴力跳fail向子节点直接转移即可 代码 #include <cstdio> #include <algorithm> #include < ...

  6. 不失一般性和快捷性地判定决策单调(洛谷P1912 [NOI2009]诗人小G)(动态规划,决策单调性,单调队列)

    洛谷题目传送门 闲话 看完洛谷larryzhong巨佬的题解,蒟蒻一脸懵逼 如果哪年NOI(放心我这样的蒟蒻是去不了的)又来个决策单调性优化DP,那蒟蒻是不是会看都看不出来直接爆\(0\)?! 还是要 ...

  7. 洛谷P3043 [USACO12JAN]牛联盟Bovine Alliance

    P3043 [USACO12JAN]牛联盟Bovine Alliance 题目描述 Bessie and her bovine pals from nearby farms have finally ...

  8. 洛谷 P3040 [USACO12JAN]贝尔分享Bale Share

    P3040 [USACO12JAN]贝尔分享Bale Share 题目描述 Farmer John has just received a new shipment of N (1 <= N & ...

  9. 「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G

    [USACO16OPEN]248 G 题目: 题目描述 Bessie likes downloading games to play on her cell phone, even though sh ...

随机推荐

  1. 认识Redis集群——Redis Cluster

    前言 Redis集群分三种模式:主从模式.sentinel模式.Redis Cluster.之前没有好好的全面理解Redis集群,特别是Redis Cluster,以为这就是redis集群的英文表达啊 ...

  2. JavaScrip_12.23

    笔记系列,零散的知识点,准备以后复习整理使用 JavaScrip - 事件DOM绑定[将函数添加到一个元素对象的属性中] 1.事件 鼠标.键盘.操作等:所有的GUI都有 onclick(单击事件) 例 ...

  3. Environment Cubemap

    要创建一个Cubemap(将您的环境捕获到一个Cubemap中),您需要去Unity Documentation复制RenderCubemapWizard.cs脚本! 然后在"Project ...

  4. phpstorm换行符设置LF

    git执行命令行 git config --global core.autocrlf true

  5. 阿里面试官:小伙子,给我说一下Spring 和 Spring Boot 的区别吧

    前言 对于 Spring和 SpringBoot到底有什么区别,我听到了很多答案,刚开始迈入学习 SpringBoot的我当时也是一头雾水,随着经验的积累.我慢慢理解了这两个框架到底有什么区别,相信对 ...

  6. 小程序ui自动化(一),用uiAutormatorViewer定位元素失败,如何解决

    1.定位元素 用android ADT自带工具:uiAutormatorViewer,会报如下错误 可能是环境与手机不兼容 可以用以下方法解决:(参考:https://blog.csdn.net/qq ...

  7. Java中类加载的过程

    类加载过程 这里的加载过程是严格按照加载开始顺序进行的,注意是加载开始而不是加载完成.也就是有可能会有两个或几个阶段是同时进行的. 比如下面提到的验证过程中的符号引用验证是在解析阶段开始之后进行. 加 ...

  8. 人人都能学会系列之ThreadLocal

    1.概览 本文我们来看下java.lang包中的ThreadLocal,它赋予我们给每个线程存储自己数据的能力. 2.ThreadLocal API ThreadLocal允许我们存储的数据只能被特定 ...

  9. nginx学习sub_filter模块

    用户替换html中的字符 location / { root /opt/app/code/; random_index on; index index.html index.htm; sub_filt ...

  10. P3694 邦邦的大合唱站队 题解

    \( 数据范围暗示状压,爪巴. \\ 首先考虑状态量. \\ 我们设计一个关于乐队数量的状态 S, 代表排列好的乐队.\\ \) eg: if(Set_排列好的队列 = {1, 2, 5}) then ...