题面

sol

设\(f_{i,j}\)表示填了前\(i\)个字母,在\(AC\)自动机上跑到了节点\(j\)的最大得分。因为匹配需要暴跳\(fail\)所以预先把\(fail\)指针上面的匹配数传下来,这样就只要计算当前节点的贡献就可以了。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N = 1005;
int n,k,tot,ch[3][N],fail[N],cnt[N],dp[N][N],ans;
char s[N];
queue<int>Q;
void Insert()
{
scanf("%s",s);int l=strlen(s);
int x=0;
for (int i=0;i<l;i++)
{
if (!ch[s[i]-'A'][x]) ch[s[i]-'A'][x]=++tot;
x=ch[s[i]-'A'][x];
}
cnt[x]++;
}
void Get_Fail()
{
for (int i=0;i<3;i++) if (ch[i][0]) Q.push(ch[i][0]);
while (!Q.empty())
{
int u=Q.front();Q.pop();
for (int i=0;i<3;i++)
if (ch[i][u]) fail[ch[i][u]]=ch[i][fail[u]],Q.push(ch[i][u]);
else ch[i][u]=ch[i][fail[u]];
cnt[u]+=cnt[fail[u]];
}
}
void DP()
{
memset(dp,-127,sizeof(dp));dp[0][0]=0;
for (int i=1;i<=k;i++)
for (int j=0;j<=tot;j++)
for (int l=0;l<3;l++)
dp[i][ch[l][j]]=max(dp[i][ch[l][j]],dp[i-1][j]+cnt[ch[l][j]]);
}
int main()
{
scanf("%d %d",&n,&k);
for (int i=1;i<=n;i++) Insert();
Get_Fail();
DP();
ans=dp[k][0];
for (int i=1;i<=tot;i++) ans=max(ans,dp[k][i]);
printf("%d\n",ans);
return 0;
}

[Luogu3041][USACO12JAN]视频游戏的连击Video Game Combos的更多相关文章

  1. [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机+DP)

    Description 贝西正在打格斗游戏.游戏里只有三个按键,分别是“A”.“B”和“C”.游戏中有 N 种连击 模式,第 i 种连击模式以字符串 Si 表示,只要贝西的按键中出现了这个字符串,就算 ...

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

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

  3. 【题解】[USACO12JAN]视频游戏的连击Video Game Combos

    好久没有写博客了,好惭愧啊……虽然这是一道弱题但还是写一下吧. 这道题目的思路应该说是很容易形成:字符串+最大值?自然联想到学过的AC自动机与DP.对于给定的字符串建立出AC自动机,dp状态dp[i] ...

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

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

  5. 【USACO12JAN】视频游戏的连击Video Game Combos

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

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

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

  7. [洛谷3041]视频游戏的连击Video Game Combos

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

  8. 【Luogu3041】视频游戏的连击(AC自动机,动态规划)

    题面链接 题解 首先构建出AC自动机 然后在AC自动机上面跑DP 转移很显然从Trie树的节点跳到他的儿子节点 但是要注意一个问题, 在计算的时候,每一个节点加入后能够 造成的贡献 要加上他的子串的贡 ...

  9. P2967 [USACO09DEC]视频游戏的麻烦Video Game Troubles

    冲刺阶段的首篇题解! 题目链接:P2967 [USACO09DEC]视频游戏的麻烦Video Game Troubles: 题目概述: 总共N个游戏平台,金额上限V元,给出每个游戏平台的价钱和其上游戏 ...

随机推荐

  1. ssh快速登录远程服务器

    以前我的做法是创建一个shell脚本运行,今天了解了可以按照下面的方式: vi .ssh/config ,写入如下内容 HOST api User abc Port HostName 123.123. ...

  2. Redis入门_上

    Redis是基于内存的Key-Value数据库,包含Set.String.SortedSet.List.Hash等数据结构,可用于缓存.排名.爬虫去重等应用场景. 1.思维导图 2.安装与配置 2.1 ...

  3. centos 环境变量配置

    CentOS系统下如何将PHP和mysql命令加入到环境变量中,在Linux CentOS系统上 安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到 ...

  4. 原生Java代码拷贝目录

    拷贝.移动文件(夹),有三方包commons-io可以用,但是有时候有自己的需求,只能使用原生java代码,这时可以用以下几种方式进行拷贝: 1.使用系统命令(Linux)调用 此种方式对操作系统有要 ...

  5. WinFom中经典小游戏(含源码)

    最近整理了若干经典的小游戏,无聊时可以打发时间.程序本身不大,练手非常不错,主要是GDI编程,主界面地址如下图所示 源码下载方式 1,关注微信公众号:小特工作室(也可直接扫描签名处二维码) 2,发送: ...

  6. 02 Java类的加载机制

    1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  7. linux开放80 端口

    1.使用su登录管理员用户 2.编辑防火墙配置文件 vim /etc/sysconfig/iptables 3.在里面加入后保存 #open port 80 -A INPUT -p TCP -m st ...

  8. 用Open SSH生成公钥和私钥(Win)

    也可以使用 dsa 加密算法进行加密,命令如下: ssh-keygen -t dsa

  9. Android 如何进行页面传递对象

    当我们从一个页面调到另一个页面的时候,需要把该页面的一些设定值也传递给下一个页面.当要传递的值很多时,我们可以传递一个对象. 页面1: Intent intent = new Intent(PageO ...

  10. 生成1~n的排列

    直接递归打印. 代码如下 #include<cstdio> void dfs(int *a,int cur,int n) { if(cur==n) { for(int i=0;i<n ...