【题目大意】

给你个模式串(每个长度≤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的更多相关文章

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

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

  2. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  3. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  4. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

  5. hdu 4117 GRE Words AC自动机DP

    题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...

  6. hdu 2457(ac自动机+dp)

    题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...

  7. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. HDU2296——Ring(AC自动机+DP)

    题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...

  9. tyvj P1519 博彩游戏(AC自动机+DP滚动数组)

    P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...

随机推荐

  1. 更改win10和mint双系统默认启动顺序

    更改win7 & Linuxmint双系统安装后更改默认启动顺序 1.打开一个term,编辑/etc/default/grub,即sudo nano /etc/default/grub,把se ...

  2. 一个IT中专生在深圳的9年辛酸经历

    一个IT中专生在深圳的9年辛酸经历 想一想来到深圳已经近10年了,感概万千呐!从一个身无分文的中专职校计算机毕业出来后,竟然大胆的南下(之前可是连我们那地区之外都没去过),现在有供完的房子,温柔的妻子 ...

  3. C# using一般用法 (转)

    using一般有着以下几种用法: 1.直接引入命名空间 a.using System ,这个是最常用的,就是using+命名空间,这样就可以直接使用命名空间中的类型,而免去了使用详细的命名空间 b.使 ...

  4. DOM常用对象

    一.select对象 HEML中的下拉列表 属性: 1.options 获得当前select下所有option 2.options[i] 获得当前select下i位置的option 3.selecte ...

  5. 【BZOJ2820】YY的GCD [莫比乌斯反演]

    YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 求1<=x<=N, ...

  6. NGINX: 反向代理 websocket

    参考: [ Using multiple nodes ] [ Nginx 官网 WebSocket proxying ] 关于 websocket 的介绍可以看阮大大的这篇 [ WebSocket 教 ...

  7. Codeforces Round #469 Div. 2 A B C D E

    A. Left-handers, Right-handers and Ambidexters 题意 \(l\)个左撇子,\(r\)个右撇子,\(a\)个两手均可.要组成一支队伍,里面用左手的人数与用右 ...

  8. HDU1010(dfs+剪枝)

    Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  9. windows使用celery遇到的错误

    https://www.jianshu.com/p/e5539d96641c 按照这个教程一步步执行到最后报错了. 运行task_dispatcher.py的时候 ValueError: not en ...

  10. jquery.qrcode生成二维码支持中文

    基本使用方法: 1.首先在页面中加入jquery库文件和qrcode插件. <script type="text/javascript" src="jquery.j ...