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

时间:2022-05-07 22:55:05

Lost's revenge

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 3757    Accepted Submission(s): 1020

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
 
Sample Output
Case 1: 3
Case 2: 2
/*
HDU 3341 Lost's revenge AC自动机+dp 给n个子串和一个字符串str,str中的位置可以随便调整.求最多可能包含多少个子串
很明显使用dp,但是在保存状态的时候出现问题. 因为有AGCT四个,那么最大需要的内存
就是40*40*40*40 超内存 但实际上是str的总长度为40,即 A+C+G+T的个数为40,那么最大需要内存的也就是10*10*10*10
这样的话dp[i][j]来保存 当前节点为i,AGCT的使用状态为j时的最大值; //dp是硬伤TAT
然后就是重复的子串也要重复计算。 hhh-2016-04-27 22:11:06
*/
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
#define lson (i<<1)
#define rson ((i<<1)|1)
typedef unsigned long long ll;
typedef unsigned int ul;
const int mod = 20090717;
const int INF = 0x3f3f3f3f;
const int N = 505;
int tot;
int n;
int dp[N][11*11*11*11+10];
int tal[10];
int num[4];
int can(int id,int wt)
{
if(wt == 0)
return id/1000000;
else if(wt == 1)
return id/10000%100;
else if(wt == 2)
return id/100%100;
else if(wt == 3)
return id%100;
} struct Tire
{
int nex[N][4],fail[N],ed[N];
int root,L;
int newnode()
{
for(int i = 0; i < 4; i++)
nex[L][i] = -1;
ed[L++] = 0;
return L-1;
} void ini()
{
L = 0,root = newnode();
} int cal(char ch)
{
if(ch == 'A')
return 0;
else if(ch == 'C')
return 1;
else if(ch == 'G')
return 2;
else if(ch == 'T')
return 3;
} void inser(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = 0; i < len; i++)
{
int ta = cal(buf[i]);
if(nex[now][ta] == -1)
nex[now][ta] = newnode();
now = nex[now][ta];
}
ed[now]++;
} void build()
{
queue<int >q;
fail[root] = root;
for(int i = 0; i < 4; i++)
if(nex[root][i] == -1)
nex[root][i] = root;
else
{
fail[nex[root][i]] = root;
q.push(nex[root][i]);
}
while(!q.empty())
{
int now = q.front();
q.pop();
ed[now] += ed[fail[now]];
for(int i = 0; i < 4; i++)
{
if(nex[now][i] == -1)
nex[now][i] = nex[fail[now]][i];
else
{
fail[nex[now][i]] = nex[fail[now]][i];
q.push(nex[now][i]);
}
}
}
} void solve(int len)
{
memset(dp,-1,sizeof(dp));
dp[0][0] = 0;
num[0] = (tal[3]+1)*(tal[1]+1)*(1+tal[2]);
num[1] = (tal[2]+1)*(tal[3]+1);
num[2] = tal[3]+1;
num[3] = 1;
for(int t0 = 0; t0 <= tal[0]; t0++)
for(int t1 = 0; t1 <= tal[1]; t1++)
for(int t2 = 0; t2 <= tal[2]; t2++)
for(int t3 = 0; t3 <= tal[3]; t3++)
for(int i = 0; i < L; i++)
{
int tn = t1*num[1]+t2*num[2]+t3+t0*num[0];
if(dp[i][tn] >= 0)
for(int k = 0; k < 4; k++)
{
int ta = nex[i][k];
if(k == 0 && t0 == tal[0])continue;
if(k == 1 && t1 == tal[1])continue;
if(k == 2 && t2 == tal[2])continue;
if(k == 3 && t3 == tal[3])continue;
dp[ta][tn+num[k]] = max(dp[ta][tn+num[k]],dp[i][tn] + ed[ta]);
}
} int ans = 0;
int ta = num[0]*tal[0]+num[1]*tal[1]+num[2]*tal[2]+num[3]*tal[3];
for(int i =0 ; i < L; i++)
{
ans = max(ans,dp[i][ta]);
}
printf("%d\n",ans);
}
}; Tire ac;
char buf[50]; int main()
{
int cas = 1;
while(scanf("%d",&n)==1 && n)
{
ac.ini(); for(int i = 0; i < n; i++)
{
scanf("%s",buf);
ac.inser(buf);
}
ac.build();
scanf("%s",buf);
memset(tal,0,sizeof(tal));
for(int i = 0; i < (int)strlen(buf) ; i++)
{
tal[ac.cal(buf[i])]++;
}
printf("Case %d: ",cas++);
ac.solve(strlen(buf));
}
return 0;
}

  

HDU 3341 Lost's revenge AC自动机+dp的更多相关文章

  1. HDU 2457 DNA repair(AC自动机&plus;DP)题解

    题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...

  2. HDU 2425 DNA repair (AC自动机&plus;DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. HDU 4758 Walk Through Squares&lpar;AC自动机&plus;DP&rpar;

    题目链接 难得出一个AC自动机,我还没做到这个题呢...这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊... #include<iostream> # ...

  4. &lbrack;HDU 4787&rsqb; GRE Words Revenge &lpar;AC自动机&rpar;

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

  5. HDU 2825 Wireless Password【AC自动机&plus;DP】

    给m个单词,由这m个单词组成的一个新单词(两个单词可以重叠包含)长度为n,且新单词中包含的基本单词数目不少于k个.问这样的新单词共有多少个? m很小,用二进制表示新单词中包含基本单词的情况. 用m个单 ...

  6. HDU3341 Lost&&num;39&semi;s revenge&lpar;AC自动机&amp&semi;&amp&semi;dp&rpar;

    一看到ACGT就会想起AC自动机上的dp,这种奇怪的联想可能是源于某道叫DNA什么的题的. 题意,给你很多个长度不大于10的小串,小串最多有50个,然后有一个长度<40的串,然后让你将这个这个长 ...

  7. hdu3341Lost&&num;39&semi;s revenge&lpar;ac自动机&plus;dp&rpar;

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

  8. HDU-3341-Lost&&num;39&semi;s revenge&lpar;AC自动机&comma; DP&comma; 压缩&rpar;

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

  9. HDU 6086 Rikka with String AC自动机 &plus; DP

    Rikka with String Problem Description As we know, Rikka is poor at math. Yuta is worrying about this ...

随机推荐

  1. USACO翻译:USACO 2014 DEC Silver三题

    USACO 2014 DEC SILVER 一.题目概览 中文题目名称 回程 马拉松 奶牛慢跑 英文题目名称 piggyback marathon cowjog 可执行文件名 piggyback ma ...

  2. linux php 安装 memcache 扩展

    1. memcached依赖于libevent,需要先安装libevent. tar zxvf libevent-2.0.21-stable.tar.gz cd libevent-2.0.21-sta ...

  3. Excel 函数记录

    1.四舍五入:round(数据,小数位数)

  4. C&plus;&plus;转义字符 &amp&semi;amp&semi; keyword

    转义字符: 换行符 \n   水平制表符\t 纵向制表符 \v 退格符 \b 回车符 \r   进纸符 \f 报警(响铃)符 \a 反斜线 \\ 疑问号 \? 单引號 \' 双引號 \"   ...

  5. 【Algorithm】逆序数的分治求解

    逆序数的分治求解,时间复杂度O(nlgn).基本思想是在归并排序的基础上加逆序计数. #include <iostream> #include <cstdio> #includ ...

  6. GDAL的RASTERIO功能

             为了能快速的显示大影像,最近一直在学习GDAL,GDAL确实是一个功能强大的开源库,其核心部分数据集和波段,下面这个图很详细的描述了它们之间的关系,还有其中的细节:     GDAL ...

  7. android 7&period;0带来的

    Android 7.0 给开发者带来了什么 新的 Andorid N (Andorid 7.0)预览版发布了,但是新的Android预览版需要我们在已存在的APP上测试几乎全部内容,包括不同种类的屏幕 ...

  8. 玩玩RMI

    今天在看代理设计模式,java中远程代理的实现一定会用到RMI的,很久没有温习过RMI的知识了,今天就重新过一遍这个知识点来让自己加深印象,构建一个简单的RMI小程序需要用到一下几个类: java.r ...

  9. UIView animateWithDuration 使用详解

    在ios4.0及以后鼓励使用animateWithDuration方法来实现动画效果.当然,以往的begin/commit的方法依然使用,下面详细解释一下animateWithDuration的使用方 ...

  10. 春天JDBC事务管理

    JDBC事务管理 春天提供编程式的事务管理(编程式事务管理)与声明式的事务管理(声明式事务management),为不同的事务实现提供了一致的编程模型,这节以JDBC事务为例,介绍Spring的事务管 ...