Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)

Total Submission(s): 3657    Accepted Submission(s): 987


Problem Description
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.
 

Input
There are less than 30 testcases.

For each testcase, first line is number of "number theory gene" N(1<=N<=50). N=0 denotes the end of the input file.

Next N lines means the "number theory gene", and the length of every "number theory gene" is no more than 10.

The last line is Lost's gene sequences, its length is also less or equal 40.

All genes and gene sequences are only contains capital letter ACGT.
 

Output
For each testcase, output the case number(start with 1) and the most "level of number theory" with format like the sample output.
 

Sample Input

3
AC
CG
GT
CGAT
1
AA
AAA
0
 

Sample Output

Case 1: 3
Case 2: 2
 
题意:给你n个模板串,每个字符串的价值为1,给你一个长度不大于40的字符串,让你重新排列字符串中的字符顺序,使得排序后字符串的总价值最大。
思路:首先容易想到统计字符串中'A','C','T','G'的个数,分别为t0,t1,t2,t3,然后用dp[i][num0][num1][num2][num3]表示当前节点为i,'A'用了num0个,'C'用了num1个,'T'用了num2个,‘G’用了num3个的最大价值。但是这样表示空间复杂度为500*40^4太大了,这样的状态表示不可行。然后我们发现其实ATCG的总个数和为40,总状态数并没有40^4那么多,所以我们采用变进制法,即用state=num0*(t1+1)*(t2+1)*(t3+1)+num1*(t2+1)*(t3+1)+num2*(t3+1)+num3表示ATCG的个数的状态,那么总的状态最大为500*11^4是可以接受的。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 99999999
#define pi acos(-1.0)
#define maxnode 500000
int t0,t1,t2,t3;
char s[14],str[50];
int cas=0;
int dp[505][15005]; struct trie{
int sz,root,val[maxnode],next[maxnode][4],fail[maxnode];
int q[1111111];
void init(){
int i;
sz=root=0;
val[0]=0;
for(i=0;i<4;i++){
next[root][i]=-1;
}
}
int idx(char c){
if(c=='A')return 0;
if(c=='C')return 1;
if(c=='T')return 2;
if(c=='G')return 3;
}
void charu(char *s){
int i,j,u=0;
int len=strlen(s);
for(i=0;i<len;i++){
int c=idx(s[i]);
if(next[u][c]==-1){
sz++;
val[sz]=0;
next[u][c]=sz;
u=next[u][c];
for(j=0;j<4;j++){
next[u][j]=-1;
}
}
else{
u=next[u][c]; } }
val[u]++;
} void build(){
int i,j;
int front,rear;
front=1;rear=0;
for(i=0;i<4;i++){
if(next[root][i]==-1 ){
next[root][i]=root;
}
else{
fail[next[root][i] ]=root;
rear++;
q[rear]=next[root][i];
}
}
while(front<=rear){
int x=q[front];
val[x]+=val[fail[x] ];
front++;
for(i=0;i<4;i++){
if(next[x][i]==-1){
next[x][i]=next[fail[x] ][i]; }
else{
fail[next[x][i] ]=next[fail[x] ][i];
rear++;
q[rear]=next[x][i];
}
}
}
}
void chazhao(){
int i,j;
int bit[4],num0,num1,num2,num3,state,state1;
for(i=0;i<=sz;i++){
for(j=0;j<=15000;j++){
dp[i][j]=-1;
}
}
dp[0][0]=0;
bit[0]=(t1+1)*(t2+1)*(t3+1);
bit[1]=(t2+1)*(t3+1);
bit[2]=t3+1;
bit[3]=1; for(num0=0;num0<=t0;num0++){
for(num1=0;num1<=t1;num1++){
for(num2=0;num2<=t2;num2++){
for(num3=0;num3<=t3;num3++){
state=bit[0]*num0+bit[1]*num1+bit[2]*num2+bit[3]*num3;
for(i=0;i<=sz;i++){
if(dp[i][state]==-1)continue;
if(num0<t0){
state1=state+bit[0];
dp[next[i][0] ][state1]=max(dp[next[i][0] ][state1],dp[i][state]+val[next[i][0] ] );
}
if(num1<t1){
state1=state+bit[1];
dp[next[i][1] ][state1]=max(dp[next[i][1] ][state1],dp[i][state]+val[next[i][1] ] );
}
if(num2<t2){
state1=state+bit[2];
dp[next[i][2] ][state1]=max(dp[next[i][2] ][state1],dp[i][state]+val[next[i][2] ] );
}
if(num3<t3){
state1=state+bit[3];
dp[next[i][3] ][state1]=max(dp[next[i][3] ][state1],dp[i][state]+val[next[i][3] ] );
}
}
}
}
}
}
int maxx=0;
state=t0*bit[0]+t1*bit[1]+t2*bit[2]+t3*bit[3];
for(i=0;i<=sz;i++){
maxx=max(maxx,dp[i][state]);
}
printf("Case %d: %d\n",++cas,maxx);
}
}ac; int main()
{
int n,m,i,j;
while(scanf("%d",&n)!=EOF && n!=0){
ac.init();
for(i=1;i<=n;i++){
scanf("%s",s);
ac.charu(s);
}
ac.build();
scanf("%s",str);
t0=t1=t2=t3=0;
int len=strlen(str);
for(i=0;i<len;i++){
if(str[i]=='A')t0++;
else if(str[i]=='C')t1++;
else if(str[i]=='T')t2++;
else t3++;
}
ac.chazhao();
}
return 0;
}

hdu3341Lost's revenge (AC自动机+变进制dp)的更多相关文章

  1. hdu3341Lost's revenge(ac自动机+dp)

    链接 类似的dp省赛时就做过了,不过这题卡内存,需要把当前状态hash一下,可以按进制来算出当前的状态,因为所有的状态数是不会超过10*10*10*10的,所以完全可以把这些存下来. 刚开始把trie ...

  2. HDU-3341-Lost's revenge(AC自动机, DP, 压缩)

    链接: https://vjudge.net/problem/HDU-3341 题意: Lost and AekdyCoin are friends. They always play "n ...

  3. HDU 3341 Lost's revenge (AC自动机 + DP + 变进制/hash)题解

    题意:给你些分数串,给你一个主串,主串每出现一个分数串加一分,要你重新排列主串,最多几分 思路:显然这里开$40^4$去状压内存不够.但是我们自己想想会发现根本不用开那么大,因为很多状态是废状压,不是 ...

  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. 『数 变进制状压dp』

    数 Description 给定正整数n,m,问有多少个正整数满足: (1) 不含前导0: (2) 是m的倍数: (3) 可以通过重排列各个数位得到n. \(n\leq10^{20},m\leq100 ...

  6. [HDU 4787] GRE Words Revenge (AC自动机)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4787 题目大意: 给你若干个单词,查询一篇文章里出现的单词数.. 就是被我水过去的...暴力重建AC自 ...

  7. hdu_3341_Lost's revenge(AC自动机+状态hashDP)

    题目链接:hdu_3341_Lost's revenge 题意: 有n个模式串,一个标准串,现在让标准串重组,使得包含最多的模式串,可重叠,问重组后最多包含多少模式串 题解: 显然是AC自动机上的状态 ...

  8. [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】

    题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...

  9. HDU - 3247 Resource Archiver (AC自动机,状压dp)

    \(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...

随机推荐

  1. MySQL中的全局锁和表级锁

    全局锁和表锁 数据库锁设计的初衷是解决并发出现的一些问题.当出现并发访问的时候,数据库需要合理的控制资源的访问规则.而锁就是访问规则的重要数据结构. 根据锁的范围,分为全局锁.表级锁和行级锁三类. 全 ...

  2. Spring框架之websocket源码完全解析

    Spring框架之websocket源码完全解析 Spring框架从4.0版开始支持WebSocket,先简单介绍WebSocket协议(详细介绍参见"WebSocket协议中文版" ...

  3. 基于B/S架构的在线考试系统的设计与实现

    前言 这个是我的Web课程设计,用到的主要是JSP技术并使用了大量JSTL标签,所有代码已经上传到了我的Github仓库里,地址:https://github.com/quanbisen/online ...

  4. 【JS学习】for-in与for-of

    前言:本博客系列为学习后盾人js教程过程中的记录与产出,如果对你有帮助,欢迎关注,点赞,分享.不足之处也欢迎指正,作者会积极思考与改正. 总述: 名称 遍历 适用 for-in 索引 主要建议白能力对 ...

  5. CICD基础概念

    windows下搭建jenkins:安装方法一:1.安装JDK,配置好环境变量2.下载安装最新版本Jenkins:登陆 http://mirrors.jenkins-ci.org/ 下载windows ...

  6. (二)React Ant Design Pro + .Net5 WebApi:前端环境搭建

    首先,你需要先装一个Nodejs,这是基础哦.如果没有这方面知识的小伙伴可以在园子里搜索cnpm yarn等关键字,内容繁多,此不赘述,参考链接 一. 简介 1. Ant Design Pro v5 ...

  7. 日常采坑:.NET Core SDK版本问题

    1..NetCore SDK版本问题 .NetCore3.1 webapi 部署linux,遇到一个坑,开启的目录浏览功能失效,几番尝试发现是版本问题.本地sdk版本与linux安装的sdk版本不对应 ...

  8. 解压rpm文件

    rpm2cpio zabbix-2.2.2-0.el6.zbx.src.rpm |cpio -div

  9. 【Spring】创建一个Spring的入门程序

    3.创建一个Spring的入门程序 简单记录 - Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)- Spring的基本应用 Spring与Spring MVC的 ...

  10. grep和egrep

    grep  nobody /etc/passwd 显示/etc/passwd中带有nobody字样的行,区分大小写 grep  -i nobody /etc/passwd 现实/etc/passwd中 ...