HDU P3341 Lost's revenge 题解+数据生成器
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 题解+数据生成器的更多相关文章
- [CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)
Problem 遗产 题目大意 给出一个带权有向图,有三种操作: 1.u->v添加一条权值为w的边 2.区间[l,r]->v添加权值为w的边 3.v->区间[l,r]添加权值为w的边 ...
- 【BZOJ3671】【NOI2014】随机数据生成器(贪心)
[BZOJ3671][NOI2014]随机数据生成器(贪心) 题面 BZOJ 题解 前面的模拟 真的就是语文阅读理解题目 理解清楚题目意思 然后就会发现要求的就是一个贪心 从小往大枚举,检查当前数能不 ...
- Mockjs,模拟数据生成器
(推荐使用)Mock.js是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试. 提供了以下模拟功能: 1. 根据数据模板生成模拟数据. 2. 模拟Ajax请求,生成并返回模拟 ...
- 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 ...
- 【awesome-dotnet-core-learning】(3)-Bogus-假数据生成器
[awesome-dotnet-core-learning](3)-Bogus-假数据生成器 简介 Bogus一个简单而强大的假数据生成器,用于C#,F#和VB.NET.从著名的faker.js移植过 ...
- 让前端独立于后端进行开发,模拟数据生成器Mock.js
让前端独立于后端进行开发,模拟数据生成器Mock.jsMock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试. Home · nuysoft/Mock Wiki ...
- 【scikit-learn】06:make_blobs聚类数据生成器
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/kevinelstri/article/ ...
- 如何从0到1的构建一款Java数据生成器-第二章
前提 在上一章我们提到了并且解决了几只拦路虎,承上启下,下面我们一起来实现一款数据生成器. 对外API /** * @description: 本地数据生成API * @author: peter * ...
- 如何从0到1的构建一款Java数据生成器-第一章
前提 某天晚上老夫在神游时,想起白天公司同事说起的问题,这老表抱怨使用mysql生成大批的随机测试数据太过麻烦,问大家有没有好的工具推荐,老夫对这种事情当然不关心,毕竟我也不知道. 秉承着不懂就要问, ...
随机推荐
- Leetcode 88 合并两个有序数组 Python
合并两个有序数组 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分 ...
- 多并发编程基础 之进程 Process
原贴 https://www.cnblogs.com/gbq-dog/p/10299663.html 1. 进程的理论知识 1.1 操作系统的背景知识 顾名思义,进程即正在执行的一个过程.进程是对正 ...
- 将python的代码文件打包成可执行文件
1.使用pip install Pyinstaller 命令安装 2.使用命令 pyinstaller -F *.py打包成exe 3.在\dist文件夹下找到exe; 一.pyinstaller ...
- 2018沈阳网络赛 - Ka Chang KD树暴力
题意:给你一棵树,n个点q次操作,操作1查询x子树深度为d的节点权值和,操作2查询子树x权值和 把每个点按(dfn,depth)的二维关系构造kd树,剩下的只需维护lazy标记即可 #include& ...
- python socket文件传输实现
简单版 server(服务端) import socket import subprocess import struct import json import os share_dir = r'E: ...
- 静态类和静态方法,抽象类和抽象方法,new关键字,值类型和引用类型,接口
静态类和静态方法:静态成员是与类相关,而非实例相关:普通类中的静态成员:1.只能通过类名访问.2.静态方法中只能访问静态成员,或通过对象访问实例成员.3.多个对象共享同一个成员.静态类(一般用作工具类 ...
- (转)sysbench部署与参数详解
sysbench部署 原文:https://wing324.github.io/2017/02/07/sysbench%E9%83%A8%E7%BD%B2/ sysbench作为每一个系统管理员,都应 ...
- ACCESS 手工注入
ACCESS的注入,基本是死的.思路很简单,基本都可以工具解决.上代码: 1.判断有无注入点' and 1=1 and 1=22.猜表一般的表的名称无非是admin adminuser user pa ...
- Hive 外部表新增字段或者修改字段类型等不生效
标题比较笼统,实际情况是: 对于Hive 的分区外部表的已有分区,在对表新增或者修改字段后,相关分区不生效. 原因是:表元数据虽然修改成功,但是分区也会对应列的元数据,这个地方不会随表的元数据修改而修 ...
- wpf 自定义ListView
1.listview.itemtemplate设置item的外层父元素的控件. 2.listview.template设置item的样式(datatemplate),也可以使用itemcontaine ...