Lost's revenge

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

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
 
Author
Qinz@XDU
 
Source
 
Recommend
lcy
 
 
 
 
字符最长是40
只需要记录ACGT出现的次数。
 
如果使用5维数组,显然超内存了。
 
假设ACGT的总数分别为num[0],num[1],num[2],num[3]
 
那么对于ACGT的数量分别为ABCD的状态可以记录为:
 
A*(num[1]+1)*(num[2]+1)*(num[3]+1) + B*(num[2]+1)*(num[3]+1)+ C*(num[3]+1) +D
 
这样的状态最大就是11*11*11*11
 
复杂度也可以承受了。
 
 
字符串可能有重复的,用int来记录数量
 
 
//============================================================================
// Name : HDU.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================ #include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
struct Trie
{
int next[][],fail[];
int end[];
int root,L;
int newnode()
{
for(int i = ;i < ;i++)
next[L][i] = -;
end[L++] = ;
return L-;
}
void init()
{
L = ;
root = newnode();
}
int getch(char ch)
{
if(ch == 'A')return ;
else if(ch == 'C')return ;
else if(ch == 'G')return ;
else return ;
}
void insert(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = ;i < len;i++)
{
if(next[now][getch(buf[i])] == -)
next[now][getch(buf[i])] = newnode();
now = next[now][getch(buf[i])];
}
end[now] ++;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ;i < ;i++)
if(next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
end[now] += end[fail[now]];/********/
for(int i = ;i < ;i++)
if(next[now][i] == -)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
int dp[][***+];
int bit[];
int num[];
int solve(char buf[])
{
int len = strlen(buf);
memset(num,,sizeof(num));
for(int i = ;i < len;i++)
num[getch(buf[i])]++;
bit[] = (num[]+)*(num[]+)*(num[]+);
bit[] = (num[]+)*(num[]+);
bit[] = (num[]+);
bit[] = ;
memset(dp,-,sizeof(dp));
dp[root][] = ;
for(int A = ;A <= num[];A++)
for(int B = ;B <= num[];B++)
for(int C = ;C <= num[];C++)
for(int D = ;D <= num[];D++)
{
int s = A*bit[] + B*bit[] + C*bit[] + D*bit[];
for(int i = ;i < L;i++)
if(dp[i][s] >= )
{
for(int k = ;k < ;k++)
{
if(k == && A == num[])continue;
if(k == && B == num[])continue;
if(k == && C == num[])continue;
if(k == && D == num[])continue;
dp[next[i][k]][s+bit[k]] = max(dp[next[i][k]][s+bit[k]],dp[i][s]+end[next[i][k]]);
}
}
}
int ans = ;
int status = num[]*bit[] + num[]*bit[] + num[]*bit[] + num[]*bit[];
for(int i = ;i < L;i++)
ans = max(ans,dp[i][status]);
return ans;
}
};
char buf[];
Trie ac;
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n;
int iCase = ;
while( scanf("%d",&n) == && n)
{
iCase++;
ac.init();
for(int i = ;i < n;i++)
{
scanf("%s",buf);
ac.insert(buf);
}
ac.build();
scanf("%s",buf);
printf("Case %d: %d\n",iCase,ac.solve(buf));
}
return ;
}
 
 
 
 
 
 
 
 
 
 
 

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

  1. 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 ...

  2. HDU 2457 DNA repair(AC自动机+DP)题解

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

  3. HDU 2425 DNA repair (AC自动机+DP)

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

  4. HDU 4758 Walk Through Squares(AC自动机+DP)

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

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

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

  6. HDU 2825 Wireless Password【AC自动机+DP】

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

  7. HDU3341 Lost's revenge(AC自动机&&dp)

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

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

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

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

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

  10. HDU 6086 Rikka with String AC自动机 + DP

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

随机推荐

  1. MPlayer-2016 最新版本

    MPlayer 和 FFmpeg 最新版本 运行 Install.cmd 添加右键播放功能 mplayer\outformat.conf 配置视频分割命令参数 ; 往前0.05秒 大概10多个帧 ' ...

  2. Ubuntu ( Linux) Eclipse 乱码问题

    刚装完Ubuntu,导入Java和Android项目时,发现字符乱码,究其原因,是由于Windows下使用的是GBK编码,而Ubuntu使用的是UTF-8编码.网上查找了相关资料,主要解决方案有两种. ...

  3. SVN客户端以及使用 for windows

    1.首先我们需要下载 "svn小乌龟"后,进行安装.比如我下载如下的: 安装完成后,比如在我的项目在qiandaun1中,我右键就可以看到如下: 说明snv已经安装成功了! 2:c ...

  4. nyoj133_子序列_离散化_尺取法

    子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次. 如2 8 ...

  5. 【leetcode】Remove Linked List Elements(easy)

    Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...

  6. iOS-WKWebView携带cookie发送http请求,cookie失效

    发送请求代码: NSString *testUrl = @"http://10.22.122.7:8081/test2_action/view_index"; NSURL *url ...

  7. C#更新SQLServer中的TimeStamp字段(时间戳) 防止同时修改一行时覆盖更新

    C#更新SQLServer中的TimeStamp字段(时间戳) 分类: C#2012-10-24 15:10 1878人阅读 评论(0) 收藏 举报 public partial class Form ...

  8. [Android Pro] http请求中传输base64出现加号变空格的解决办法

    reference to : http://blog.csdn.net/jsjwbxzy/article/details/45970231 try { des = URLEncoder.encode( ...

  9. 在linux中,rpm和yum有什么区别?

    rpm是由红帽公司开发的软件包管理方式,使用rpm我们可以方便的进行软件的安装.查询.卸载.升级等工作.但是rpm软件包之间的依赖性问题往往会很繁琐,尤其是软件由多个rpm包组成时.Yum(全称为 Y ...

  10. JS_ECMA基本语法中的几种封装的小函数-1

    今天给大家介绍js ECMA中几个封装的小函数以及一些常用的函数小案例: 1,找重复的函数 <script> //在数组里面找重复: function findInArr(n,arr){ ...