【题目大意】

给你个模式串(每个长度≤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. idea设置文件的编码格式

    在打开某些类时会发现注释是乱码的,该如何解决idea的文件乱码呢?这就需要设置这个文件的合适编码格式: idea设置文件编码的两种方式分别如下: 第一种方式点击idea的右下角的图标如下图所示: 第二 ...

  2. event对象和事件冒泡

    <!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title>无标 ...

  3. iOS12、iOS11、iOS10、iOS9常见适配

    作者:花丶满楼 链接:https://juejin.im/post/5c49a7d0518825254e4d46fc 一.iOS12(Xcode10) 1.1.升级Xcode10后项目报错 不允许多个 ...

  4. powercmd注册码

    推荐一个很方便的软件:powercmd 用户名:nzone 注册码:PCMDA-86128-PCMDA-70594  . 下载地址网上很多: http://soft.hao123.com/soft/a ...

  5. python最简单发送邮件

    #!/usr/bin/env python #coding:utf8 #Author:lsp #Date:下午5:51:13 #Version:0.1 #Function: #导入smtplib和MI ...

  6. C++中的各种“神奇”东西

    将光标放到任意的位置 void gotoxy(int x,int y)//位置函数 { COORD pos; pos.X=x; pos.Y=y; SetConsoleCursorPosition(Ge ...

  7. Apache多网站虚拟目录域名

    一台服务器安装了Apache,如何绑定多个域名或网站呢? 最简单高效的方法如下: 1. 先打开Apache的配置文件httpd.conf,在这个文件, 找到这句:“#Include etc/extra ...

  8. bzoj 1293 贪心

    首先我们可以将这道题看成一个数轴,数轴其中的某些点存在一些颜色,我们要选取最短的一段,使这段存 在所有颜色,那么我们使用指针i,j表示在j-i位置中包含的颜色,那么初值是0,0,我们先i++,同时添加 ...

  9. hdu 1399 Starship Hakodate-maru (暴力搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1399 题目大意:找到满足i*i*i+j*(j+1)*(j+2)/6形式且小于等于n的最大值. #inc ...

  10. python中的scapy模块

    scapy模块是干嘛用的? 答:Scapy的是一个强大的交互式数据包处理程序(使用python编写).它能够伪造或者解码大量的网络协议数据包,能够发送.捕捉.匹配请求和回复包等等.它可以很容易地处理一 ...