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. 机器学习算法·KNN

    机器学习算法应用·KNN算法 一.问题描述 验证码目前在互联网上非常常见,从学校的教务系统到12306购票系统,充当着防火墙的功能.但是随着OCR技术的发展,验证码暴露出的安全问题越来越严峻.目前对验 ...

  2. Spring AOP之多切面运行顺序

    多切面运行顺序 当一个方法的执行被多个切面共同切的时候,环绕通知只影响当前切面的通知顺序,例如创建两个切面logUtil,validateUtil两个切面共同监视计算器类的加法运算,add(int a ...

  3. python模块/文件/日期时间

    文件操作:

  4. html2canvas canvas webgl 截图透明空🤣

    1. React用这个插件html2canvas完成div截图功能,div里面嵌套canvas,返回base64是透明图片. html2canvas(document.getElementById(& ...

  5. AgileConfig - RESTful API 介绍

    AgileConfig AgileConfig是一个基于.net core开发的轻量级配置中心. AgileConfig秉承轻量化的特点,部署简单.配置简单.使用简单.学习简单,它只提取了必要的一些功 ...

  6. kubernets之Replication Controller

    一  Replication Controller的介绍      pod可能会由于各种原因消失和多出来,例如node节点去除集群或者人为的手工创建,所以为了方便和管理pod的数量,k8s里面 的另外 ...

  7. Jenkins 部署打包文件 并通过SSH上传到 linux服务器

    编译 发布 打包成zip文件 dotnet clean : dotnet的命令清除解决方案 dotnet build : dotnet的命令重新生成 dotnet publish .\Hy.MyDem ...

  8. Linux内核分析_课程学习总结报告

    请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的.自洽的,并举例某一两个具体例子(比如读写文件.分配内存.使用I/O ...

  9. 阿里云RDS物理备份恢复到本地

    一:业务场景 验证阿里云备份文件可用性 二:恢复到本地过程中遇到的问题 1.修改密码报错 2.自定义函数不可用 三:恢复步骤 1.xtrabackup安装使用 请参考:https://www.cnbl ...

  10. 上海某小公司面试题:synchronized锁原理

    synchronized锁是Java面试的过程中比较常考的知识点了,从偏向锁->轻量级锁->重量级锁都可以聊 CAS在这篇没有讲述,因为在上一篇已经写了,有兴趣的同学可以翻翻开 目前已经连 ...