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. 关于类的成员,public,private修饰符

    类的成员要:属性,方法 属性:是它本身所居有的东西,比如人的特征,也可以这样理解属性是静态状态 方法:是这些属性通过方法行为发生改变,也就是方法是动态,可以对属性进行更新 public 公共的,可以被 ...

  2. 利用atimicInteger cas的特性实现一个锁

    利用atimicInteger cas的特性实现一个锁 主要是使用的是 atomicIntegerAPI 的compareAndSet()方法,让线程不在阻塞,获取不到直接失败. 我们先定义一个异常类 ...

  3. webpack/gulp的z-index被改写

    webpack方法 new OptimizeCSSPlugin({ cssProcessorOptions: { safe: true } }) gulp-cssnano 方法 .pipe(cssna ...

  4. Mac 10.12安装hosts快速切换工SwitchHosts!

    说明:支持在线本地. 下载: (链接: https://pan.baidu.com/s/1boDw67d 密码: uy6g)

  5. html网页如何传递接收地址参数?

    实现html页面的参数传递 方法一: 下面是javascrīpt的一种实现方法, 这个函数是通过window.location.href中的分割符获得各个参数. 有了这个函数,就可以在页面之间传递参数 ...

  6. docker相关命令

    1. 进入docker容器 ① 查看运行的容器:docker ps -a ②  进入容器:docker exec -ti [容器id] bash ③ 退出容器:eixt

  7. 模块和处理程序之通过HttpModule和HttpHandler拦截入站HTTP请求执行指定托管代码模块

    1.简介 大多数情况下,作为一个asp.net web开发对整个web应用程序的控制是十分有限的,我们的控制往往只能做到对应用程序(高层面)的基本控制.但是,很多时候,我们需要能够低级层面进行交互,例 ...

  8. 19.Class的基本语法

    1.简介 JavaScript 语言中,生成实例对象的传统方法是通过构造函数. function Point(x, y) { this.x = x; this.y = y; } Point.proto ...

  9. 全网最详细的Git学习系列之介绍各个Git图形客户端(Windows、Linux、Mac系统皆适用ing)(图文详解)

    不多说,直接上干货! 一.TortoiseGit - The coolest Interface to Git Version Control TortoiseGit 是 TortoiseSVN 的  ...

  10. Unix/Linux文件类型及访问权限

    在Linux系统中,有7种文件类型. 普通文件 (regular file) 目录文件 (directory) 链接文件 (symbolic link) 管道文件 (FIFO) 套接字文件 (sock ...