【AC自动机+DP】USACO2012 JAN GOLD_Video Game Combos
【题目大意】
给你个模式串(每个长度≤15,1≤N≤20),串中只含有三种字母。求一长度为K(1≤K≤1000)的字符串,使得匹配数最大(重复匹配计多次),输出最大值。
【解题思路】
W老师给的题,然而我不会做。呜呜呜谢谢丁爷爷教我做题,神犇丁爷爷%%%。下面都是丁爷爷的话,和我没有关系。然而丁爷爷没有博客(也许是我不造?( •̀ ω •́ )y)现在正在码USACO给的标答…
COPYRIGHT@丁爷爷
代码是我自己的,因为是用指针写的会有点长,丁爷爷的代码只有60+。总之祝丁爷爷继续超神下去……
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define lnum 3
using namespace std;
const int MAXK=;
const int MAXN=*+;
int cnt=-;
struct ACauto
{
int id;
ACauto* next[lnum];
ACauto* fail;
ACauto()
{
id=++cnt;
for (int i=;i<lnum;i++) next[i]=NULL;
fail=NULL;
}
};
ACauto* rt=new ACauto();
int go[MAXN][lnum];//编号为i的节点的三个后继的编号,如果不存在则为0
int combo[MAXN];//编号为i的节点及其后缀能够产生的最大匹配数
int dp[MAXN][MAXK];//在编号为i的节点上再走j步能够达到的最大值
int n,k; void insert(ACauto* rt,char* str)
{
int len=strlen(str);
ACauto* now=rt;
for (int i=;i<len;i++)
{
int index=str[i]-'A';
if (now->next[index]==NULL)
{
now->next[index]=new ACauto();
}
go[now->id][index]=now->next[index]->id;
now=now->next[index];
}
combo[now->id]=;
//在不包含后缀的情况下,当前结尾可以产生一个匹配
} void buildfail(ACauto* rt)
{
queue<ACauto*> que;
que.push(rt);
while (!que.empty())
{
ACauto* head=que.front();que.pop();
for (int i=;i<lnum;i++)
{
if (head->next[i]==NULL) continue;
if (head==rt)
head->next[i]->fail=rt;
else
{
ACauto* tmp=head->fail;
while (tmp!=NULL)
{
if (tmp->next[i]!=NULL)
{
head->next[i]->fail=tmp->next[i];
break;
}
else
tmp=tmp->fail;
}
if (tmp==NULL) head->next[i]->fail=rt;
}
combo[head->next[i]->id]+=combo[head->next[i]->fail->id];
//当前节点及其字符串后缀的节点均可能为模式串,故每次都要沿着指针计算这一步能够产生的新的匹配数。由于计算时累加的,只需沿fail指针走一步即可。
que.push(head->next[i]);
}
}
} void init()
{
memset(go,,sizeof(go));
memset(combo,,sizeof(combo));
scanf("%d%d",&n,&k);
for (int i=;i<n;i++)
{
char str[];
scanf("%s",str);
insert(rt,str);
}
buildfail(rt);
} void dp_process()
{
memset(dp,,sizeof(dp));
for (int i=;i<=cnt;i++) dp[][i]=combo[i];
int cur=;
for (int l=;l<=k;l++)
{
cur^=;
for (int i=;i<=cnt;i++)
{
dp[cur][i]=;
for (int j=;j<lnum;j++)
dp[cur][i]=max(dp[cur][i],combo[i]+dp[cur^][go[i][j]]);
}
}
printf("%d",dp[cur][]);
} int main()
{
init();
dp_process();
return ;
}
【AC自动机+DP】USACO2012 JAN GOLD_Video Game Combos的更多相关文章
- 洛谷P3041 视频游戏的连击Video Game Combos [USACO12JAN] AC自动机+dp
正解:AC自动机+dp 解题报告: 传送门! 算是个比较套路的AC自动机+dp趴,,, 显然就普普通通地设状态,普普通通地转移,大概就f[i][j]:长度为i匹配到j 唯一注意的是,要加上所有子串的贡 ...
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 2457(ac自动机+dp)
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2296——Ring(AC自动机+DP)
题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...
- tyvj P1519 博彩游戏(AC自动机+DP滚动数组)
P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...
随机推荐
- java类中获取WEB-INF路径
WEB-INF路径 String path = WsTestBOImpl.class.getClass().getResource("/").getPath(); path = p ...
- 利用java.lang.reflect.Constructor动态实例化对象
} } } } } Student t = co ...
- 有关eclipse的内存溢出问题
一:前言 最近在做的项目在启动tomcat时就报“内存溢出的错误”,其实也不是自己第一次遇到,但是每次都是在网上查询后敲进去,所以这次我觉得自己记载下来吧. 二:内容 我自己的配置大小,这里的配置位置 ...
- Python基础(5)_文件操作
一.文件处理流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 二.文件打开模式 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文 ...
- POJ3682 King Arthur's Birthday Celebration
King Arthur is an narcissist who intends to spare no coins to celebrate his coming K-th birthday. Th ...
- bzoj3786 星际探索 splay dfs序
这道题 首先 因为他求的是当前点到根节点的路径和 我们可以将题目转换为括号序列的写法 将点拆为左括号以及右括号 左括号为正 右括号为负 这样题目就变为了求前缀和了 如果一个点是这个点的子树 那么他的左 ...
- hdu3294 manacher算法
这道题哇 其实是裸的manacher 无论怎么变 是回文的就是回文 所以 特殊处理一下输出就好了 不过最后的左右端点l,r.l=(p-p[pos]+2)/2-1,r=(p+p[pos]-2)/2-1; ...
- [Leetcode Week3]Course Schedule
Course Schedule题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/course-schedule/description/ Descript ...
- Linux下的Backlight子系统(二)【转】
转自:http://blog.csdn.net/weiqing1981127/article/details/8515847 版权所有,转载必须说明转自 http://my.csdn.net/weiq ...
- 表单重置 jQuery
//重置 $('.reset-bottom').click(function(){ $('.mui-input-clear').attr('value','');//text类型 $('input[n ...
COPYRIGHT@丁爷爷