【题解】[USACO12JAN]视频游戏的连击Video Game Combos
好久没有写博客了,好惭愧啊……虽然这是一道弱题但还是写一下吧。
这道题目的思路应该说是很容易形成:字符串+最大值?自然联想到学过的AC自动机与DP。对于给定的字符串建立出AC自动机,dp状态dp[i][j]则表示第i位(我们求的字符串的第i位),匹配到自动机的第j位所能获得的最大值。只需要沿儿子节点与fail指针转移即可。
#include <bits/stdc++.h>
using namespace std;
#define maxn 1005
int n, m, ans, cnt;
int dp[maxn][maxn], ch[maxn][], tag[maxn * ], fail[maxn * ];
string s; void Gmax(int &x, int y)
{
if(y > x) x = y;
} void Trie_Ins()
{
int len = s.length(), now = ;
for(int i = ; i < len; i ++)
{
if(!ch[now][s[i] - 'A']) ch[now][s[i] - 'A'] = ++ cnt;
now = ch[now][s[i] - 'A'];
}
tag[now] += ;
} void AC_Build()
{
queue <int> q;
for(int i = ; i < ; i ++)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i = ; i < ; i ++)
{
if(ch[u][i])
{
fail[ch[u][i]] = ch[fail[u]][i];
tag[ch[u][i]] += tag[fail[ch[u][i]]];//注意不是加1哦
q.push(ch[u][i]);
}
else ch[u][i] = ch[fail[u]][i];
}
}
} void DP()
{
dp[][] = ;
for(int i = ; i <= m; i ++)
for(int j = ; j <= cnt; j ++)
{
if(dp[i - ][j] == -) continue;
for(int k = ; k < ; k ++)
{
if(ch[j][k]) Gmax(dp[i][ch[j][k]], dp[i - ][j] + tag[ch[j][k]]);
else Gmax(dp[i][fail[ch[j][k]]], dp[i - ][j] + tag[fail[ch[j][k]]]);
}
}
} int main()
{
scanf("%d%d", &n, &m);
memset(dp, -, sizeof(dp));
for(int i = ; i <= n; i ++)
{
cin >> s;
Trie_Ins();
}
AC_Build();
DP();
for(int i = ; i <= cnt; i ++) ans = max(ans, dp[m][i]);
printf("%d\n", ans);
return ;
}
【题解】[USACO12JAN]视频游戏的连击Video Game Combos的更多相关文章
- [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机+DP)
Description 贝西正在打格斗游戏.游戏里只有三个按键,分别是“A”.“B”和“C”.游戏中有 N 种连击 模式,第 i 种连击模式以字符串 Si 表示,只要贝西的按键中出现了这个字符串,就算 ...
- [Luogu3041][USACO12JAN]视频游戏的连击Video Game Combos
题面 sol 设\(f_{i,j}\)表示填了前\(i\)个字母,在\(AC\)自动机上跑到了节点\(j\)的最大得分.因为匹配需要暴跳\(fail\)所以预先把\(fail\)指针上面的匹配数传下来 ...
- P3041 [USACO12JAN]视频游戏的连击Video Game Combos
思路 简单的AC自动机上dp,暴力跳fail向子节点直接转移即可 代码 #include <cstdio> #include <algorithm> #include < ...
- 【洛谷 P3041】 [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机,dp)
题目链接 手写一下AC自动机(我可没说我之前不是手写的) Trie上dp,每个点的贡献加上所有是他后缀的串的贡献,也就是这个点到根的fail链的和. #include <cstdio> # ...
- 【USACO12JAN】视频游戏的连击Video Game Combos
题目描述 Bessie is playing a video game! In the game, the three letters 'A', 'B', and 'C' are the only v ...
- 洛谷P3041 视频游戏的连击Video Game Combos [USACO12JAN] AC自动机+dp
正解:AC自动机+dp 解题报告: 传送门! 算是个比较套路的AC自动机+dp趴,,, 显然就普普通通地设状态,普普通通地转移,大概就f[i][j]:长度为i匹配到j 唯一注意的是,要加上所有子串的贡 ...
- [洛谷3041]视频游戏的连击Video Game Combos
题目描述 Bessie is playing a video game! In the game, the three letters 'A', 'B', and 'C' are the only v ...
- P2967 [USACO09DEC]视频游戏的麻烦Video Game Troubles
冲刺阶段的首篇题解! 题目链接:P2967 [USACO09DEC]视频游戏的麻烦Video Game Troubles: 题目概述: 总共N个游戏平台,金额上限V元,给出每个游戏平台的价钱和其上游戏 ...
- 视频游戏的连击 [USACO12JAN](AC自动机+动态规划)
传送门 默认大家都学过trie与AC自动机. 先求出fail,对于每个节点维护一个sum,sum[u]待表从根到u所形成的字符串能拿到几分.显然sum[u]=sum[fail] + (u是几个字符串的 ...
随机推荐
- java常见面试问题.你一定会预见到。
1判断一个char字符是不是数字:Character.isDigit(char).是数字返回true,反之返回false. 2字符串的toCharArray() 把字符串转换为字符数组.返回char[ ...
- PHP计算两个时间戳之间间隔时分秒
/功能:计算两个时间戳之间相差的日时分秒//$begin_time 开始时间戳//$end_time 结束时间戳function timediff($begin_time,$end_time){ if ...
- Python学习 :深浅拷贝
深浅拷贝 一.浅拷贝 只拷贝第一层数据(不可变的数据类型),并创建新的内存空间进行储蓄,例如:字符串.整型.布尔 除了字符串以及整型,复杂的数据类型都使用一个共享的内存空间,例如:列表 列表使用的是同 ...
- python装饰器+递归+冒泡排序
冒泡排序 li = [33, 2, 10, 1,23,23523,5123,4123,1,2,0] for k in range(1,len(li)): for i in range(len(li) ...
- HDU1209:Clock
参考:https://blog.csdn.net/libin56842/article/details/8990530 https://blog.csdn.net/u011479875/article ...
- 1698-Just a Hook 线段树(区间替换)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- IAR工程名修改
修改.dep..ewd..ewp..eww四个文件的文件名 删除.ewt文件(如果存在) 记事本打开.eww文件,修改<path></path>间的.ewp文件名 打开工程,打 ...
- Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org/apache/hadoop/hbase/
Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org/apache/hadoop/hbase/ ...
- LINUX系统配置相关
修改系统引导文件 grub.cfg的文件位置 /boot/grub/grub.cfg set default="4" 默认windows是在第四个选项 set timeout ...
- JAXB轻松转换xml对象和java对象
实体类如下: package com.cn.entity; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; ...