Lost and AekdyCoin are friends. They always play "number game"(A boring game based on number theory) together. We all know that AekdyCoin is the man called "nuclear weapon of FZU,descendant of Jingrun", because of his talent in the field of number theory. So Lost had never won the game. He was so ashamed and angry, but he didn't know how to improve his level of number theory.

One
noon, when Lost was lying on the bed, the Spring Brother poster on the wall(Lost
is a believer of Spring Brother) said hello to him! Spring Brother said, "I'm
Spring Brother, and I saw AekdyCoin shames you again and again. I can't bear my
believers were being bullied. Now, I give you a chance to rearrange your gene
sequences to defeat AekdyCoin!".

It's soooo crazy and unbelievable to
rearrange the gene sequences, but Lost has no choice. He knows some genes called
"number theory gene" will affect one "level of number theory". And two of the
same kind of gene in different position in the gene sequences will affect two
"level of number theory", even though they overlap each other. There is nothing
but revenge in his mind. So he needs you help to calculate the most "level of
number theory" after rearrangement.

              ——by HDU;

http://acm.hdu.edu.cn/showproblem.php?pid=3341



就是,有N个由'A'C'G'T'构成的KEY串,给一个可以改变顺序的word串,求最多匹配(KEY可重复使用)

AC自动机+DP

f[i][num0][num1][num2][num3]

表示当前在AC自动机i点,'A'用了num0个,'C'用了num1个......

于是她可以转移到她的所有子节点及子节点的fail链上

但是显然因为num0~3他们的范围的问题(你只能每个都开到word串的长这么大,就是40),这样会MLE(自己算算咯)

发现数组开的很冗余;

于是考虑状态压缩(还是hash???)

反正把num0~num3压到数组的一维里,对num0而言每个1在压缩后为该维贡献1(sum0=1),对num1而言每个1在压缩后则为该维贡献1*(num0+1)(sum1=num0+1),对num1而言每个1在压缩后则为该维贡献1*(num1+1)*sum1(sum2=(num1+1)*sum1).......

这样把原状态的后4维按权(sum)压到一维里

可以看出,这样压缩后不会有多余的空间;

那么开出的数组就是点数i*(num0+1)*(num1+1)*(num2+1)*(num3+1)(组合数学吧)

最大也就num0~3均取10——也不是很大呢

代码如下:

 #include<cstdio>
#include<cstring>
using namespace std;
struct ss{
int ch[];
}x[];
int n,tot;
int is_end[],fail[];
int que[];
char key[],word[];
int num[],sum[],f[][];
int boo(int ,int ,int ,int ,int );
void bfs_fail();
int dp();
int pd(char );
int main(){
int i,j,k,len,T=;
while(){
scanf("%d",&n);
if(!n)
return ;
tot=;
memset(is_end,,sizeof(is_end));
memset(fail,,sizeof(fail));
memset(x,,sizeof(x));
for(i=;i<=;i++)
num[i]=,sum[i]=;
for(i=;i<=n;i++){
scanf("%s",key);
len=strlen(key)-;k=;
for(j=;j<=len;j++){
if(!x[k].ch[pd(key[j])])
x[k].ch[pd(key[j])]=++tot;
k=x[k].ch[pd(key[j])];
}
is_end[k]++;
}
bfs_fail();
scanf("%s",word);len=strlen(word)-;
for(i=;i<=len;i++)
num[pd(word[i])]++;
sum[]=;
for(i=;i<=;i++)sum[i]=sum[i-]*(num[i-]+);
printf("Case %d: %d\n",++T,dp());
}
return ;
}
int boo(int i,int j,int k,int l,int p){
int x;
switch (p){
case :x=i;break;
case :x=j;break;
case :x=k;break;
case :x=l;break;
}
if(num[p]-x->=)
return ;
return ;
}
void bfs_fail(){
int h=,t=,i,j,k;
while(h<t){
++h;
for(i=;i<=;i++)
if(x[que[h]].ch[i]){
j=que[h];
while(){
if(x[j].ch[i]&&j!=que[h]){
fail[x[que[h]].ch[i]]=x[j].ch[i];
break;
}
else{
if(!j)
break;
j=fail[j];
}
}
que[++t]=x[que[h]].ch[i];
}
}
}
int dp(){
memset(f,-,sizeof(f));f[][]=;
int i,j,k,l,o,p,q,r,ans=-;
for(i=;i<=num[];i++)
for(j=;j<=num[];j++)
for(k=;k<=num[];k++)
for(l=;l<=num[];l++)
for(o=;o<=tot;o++)
if(f[o][i*sum[]+j*sum[]+k*sum[]+l*sum[]]!=-)
for(p=;p<=;p++)
if(x[o].ch[p]&&boo(i,j,k,l,p)){
r=x[o].ch[p];q=;
while(r){
q+=is_end[r];
r=fail[r];
}
r=x[o].ch[p];
while(){
f[r][i*sum[]+j*sum[]+k*sum[]+l*sum[]+sum[p]]=f[r][i*sum[]+j*sum[]+k*sum[]+l*sum[]+sum[p]]>f[o][i*sum[]+j*sum[]+k*sum[]+l*sum[]]+q?f[r][i*sum[]+j*sum[]+k*sum[]+l*sum[]+sum[p]]:f[o][i*sum[]+j*sum[]+k*sum[]+l*sum[]]+q;
if(!r)break;
r=fail[r];
}
}
q=sum[]*num[]+sum[]*num[]+sum[]*num[]+sum[]*num[];
for(i=;i<=tot;i++)
for(j=;j<=q;j++)
if(ans<f[i][j])
ans=f[i][j];
return ans;
}
int pd(char a){
int i;
switch (a) {
case 'A':i=;break;
case 'C':i=;break;
case 'G':i=;break;
case 'T':i=;break;
}
return i;
}

由于本人也在这个题上卡了好久,故放上数据生成器:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
char s[]={'A','C','G','T'};
int main()
{
freopen("input.txt","w",stdout);
srand(time());
int T=,n,l;
for(int i=;i<=T;i++){
n=rand()%+;
printf("%d\n",n);
for(int j=;j<=n;j++){
l=rand()%+;
for(int k=;k<=l;k++)
printf("%c",s[rand()%]);
printf("\0");printf("\n");
}
l=rand()%+;
for(int k=;k<=l;k++)
printf("%c",s[rand()%]);
printf("\0");printf("\n");
}
printf("");
}

data

祝AC

HDU P3341 Lost's revenge 题解+数据生成器的更多相关文章

  1. [CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)

    Problem 遗产 题目大意 给出一个带权有向图,有三种操作: 1.u->v添加一条权值为w的边 2.区间[l,r]->v添加权值为w的边 3.v->区间[l,r]添加权值为w的边 ...

  2. 【BZOJ3671】【NOI2014】随机数据生成器(贪心)

    [BZOJ3671][NOI2014]随机数据生成器(贪心) 题面 BZOJ 题解 前面的模拟 真的就是语文阅读理解题目 理解清楚题目意思 然后就会发现要求的就是一个贪心 从小往大枚举,检查当前数能不 ...

  3. Mockjs,模拟数据生成器

    (推荐使用)Mock.js是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试. 提供了以下模拟功能: 1. 根据数据模板生成模拟数据. 2. 模拟Ajax请求,生成并返回模拟 ...

  4. HDU 3341 Lost's revenge AC自动机+dp

    Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

  5. 【awesome-dotnet-core-learning】(3)-Bogus-假数据生成器

    [awesome-dotnet-core-learning](3)-Bogus-假数据生成器 简介 Bogus一个简单而强大的假数据生成器,用于C#,F#和VB.NET.从著名的faker.js移植过 ...

  6. 让前端独立于后端进行开发,模拟数据生成器Mock.js

    让前端独立于后端进行开发,模拟数据生成器Mock.jsMock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试. Home · nuysoft/Mock Wiki ...

  7. 【scikit-learn】06:make_blobs聚类数据生成器

      版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/kevinelstri/article/ ...

  8. 如何从0到1的构建一款Java数据生成器-第二章

    前提 在上一章我们提到了并且解决了几只拦路虎,承上启下,下面我们一起来实现一款数据生成器. 对外API /** * @description: 本地数据生成API * @author: peter * ...

  9. 如何从0到1的构建一款Java数据生成器-第一章

    前提 某天晚上老夫在神游时,想起白天公司同事说起的问题,这老表抱怨使用mysql生成大批的随机测试数据太过麻烦,问大家有没有好的工具推荐,老夫对这种事情当然不关心,毕竟我也不知道. 秉承着不懂就要问, ...

随机推荐

  1. UDP的优点

    UDP优点 关于何时.发送什么数据的应用层控制更为精细 只需要应用层把数据传给UDP,UDP就把数据打包到网络层.对于TCP来说,存在一个拥塞控制机制,当链路变得拥塞时,会抑制TCP发送方,并造成数据 ...

  2. Eclipse署动态web项目方法

    和MyEclipse不一样,在Eclipse中做的Web项目默认是不支持将项目发布到Web服务器上的,会发布到工作空间的某个目录,因此无法在外部启动Tomcat来运行Web项目,只有打开Eclipse ...

  3. C#-WebForm-网页中Form表单中给回车绑定按钮

    WEB端:     <form id="form1" runat="server" defaultbutton="btnSearch" ...

  4. ThreadLocal系列(一)-ThreadLocal的使用及原理解析

    ThreadLocal系列之ThreadLocal(源码基于java8) 项目中我们如果想要某个对象在程序运行中的任意位置获取到,就需要借助ThreadLocal来实现,这个对象称作线程的本地变量,下 ...

  5. Github概念理解备忘录

    总结: add就是用来建立跟踪,添加文件到缓存区: commit就是把文件缓存区的文件正式加到本地库中: push就是把本地库更新到远程库中: git命令的操作要在仓库所在目录下进行才有效: 在Git ...

  6. python全栈开发_day17_时间,系统模板和序列化

    一:时间模板 1)time 常用功能: time.sleep() time.time() time.strftime() import time print(time.strftime("% ...

  7. Typecho V1.1反序列化导致代码执行分析

    0x00  前言     今天在Seebug的公众号看到了Typecho的一个前台getshell分析的文章,然后自己也想来学习一下.保持对行内的关注,了解最新的漏洞很重要. 0x01  什么是反序列 ...

  8. Guava源码解析之EventBus

    最近看Elastic-Job源码,看到它里面实现的任务运行轨迹的持久化,使用的是Guava的AsyncEventBus,一个内存级别的异步事件总线服务,实现了简单的生产-消费者模式,从而在不影响任务执 ...

  9. python-锁机制

    锁 Lock() Lock(指令锁)是可用的最低级的同步指令.Lock处于锁定状态时,不被特定的线程拥有.Lock包含两种状态——锁定和非锁定,以及两个基本的方法. 可以认为Lock有一个锁定池,当线 ...

  10. 初始设置ubuntu 16.04 Vps部署rails

    参考 https://blog.longwin.com.tw/2005/12/ssh_keygen_no_passwd/ 1 选择搬瓦工左边菜单栏中的“Root password modificati ...