Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)
标题效果:
举个很多种DNA弦,每个字符串值值至1。最后,一个长字符串。要安排你最后一次另一个字符串,使其没事子值和最大。
IDEAS:
首先easy我们的想法是想搜索的!管她3721。。直接一个字符一个字符的码,然后在AC自己主动机上推断最后的权值。TLE哟。
然后发现搜过不去。那就dp咯。再easy想到的就是dp[i][a][b][c][d] 表示此时遍历AC自己主动机的节点在i,然后构成了a个A,b个G,c个C。d个T的权值。
再一看内存,500*40*40*40*40...然后。。。就没有然后了
再想,由于它说的是这个串的长度是40。所以最多的状态就是10*10*10*10.。,所以开40^4就是浪费。所以要把状态hash下来。
关于hash ...cnt[0]-cnt[3] 表示ACGT的数量。 如今表示ABCD个ACGT 就是A*(cnt[3]+1)*(cnt[2]+1)*(cnt[1]+1)+B*(cnt[2]+1)*(cnt[1]+1)+C*(cnt[1]+1)+D*1
然后就依照上面的五维dp去做就好啦。
坑点就是。
。又有反复的串,人与人之间最主要的信任都没有。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <utility>
#define inf 0x3f3f3f3f
#include <vector>
using namespace std; const char tab = 0;
const int max_next = 4;
int idx;
struct trie
{
struct trie *fail;
struct trie *next[max_next];
int isword;
int index;
};
int rev[256];
trie *que[100005],ac[100005];
int head,tail;
trie *New()
{
trie *temp=&ac[idx];
for(int i=0;i<max_next;i++)temp->next[i]=NULL;
temp->fail=NULL;
temp->isword=0;
temp->index=idx++;
return temp;
}
void Insert(trie *root,char *word,int len){
trie *t=root;
for(int i=0;i<len;i++){
if(t->next[rev[word[i]]]==NULL)
t->next[rev[word[i]]]=New();
t=t->next[rev[word[i]]];
}
t->isword++;
} void acbuild(trie *root){
int head=0,tail=0;
que[tail++]=root;
root->fail=NULL;
while(head<tail){
trie *temp=que[head++],*p;
for(int i=0;i<max_next;i++){
if(temp->next[i]){
if(temp==root)temp->next[i]->fail=root;
else {
p=temp->fail;
while(p!=NULL){
if(p->next[i]){
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)temp->next[i]->fail=root;
}
if(temp->next[i]->fail->isword)temp->next[i]->isword+=temp->next[i]->fail->isword;
que[tail++]=temp->next[i];
}
else if(temp==root)temp->next[i]=root;
else temp->next[i]=temp->fail->next[i];
}
}
}
void del()
{
for(int i=0;i<idx;i++)
free(&ac[i]);
}
void tra()
{
for(int i=0;i<idx;i++)
{
if(ac[i].fail!=NULL)printf("fail = %d ",ac[i].fail->index);
for(int k=0;k<max_next;k++)
printf("%d ",ac[i].next[k]->index);
puts("");
}
}
char word[50];
int cnt[5];
int dp[515][11*11*11*11+5];
int bit[5];
int solve()
{
memset(dp,-1,sizeof dp);
dp[0][0]=0;
bit[0]=(cnt[1]+1)*(cnt[2]+1)*(cnt[3]+1);
bit[1]=(cnt[2]+1)*(cnt[3]+1);
bit[2]=(cnt[3]+1);
bit[3]=1;
for(int A=0;A<=cnt[0];A++)
{
for(int B=0;B<=cnt[1];B++)
{
for(int C=0;C<=cnt[2];C++)
{
for(int D=0;D<=cnt[3];D++)
{
int state=A*bit[0]+B*bit[1]+C*bit[2]+D*bit[3];
for(int i=0;i<idx;i++)
{
if(dp[i][state]>=0)
{
for(int k=0;k<4;k++)
{
if(k==0 && A==cnt[0])continue;
if(k==1 && B==cnt[1])continue;
if(k==2 && C==cnt[2])continue;
if(k==3 && D==cnt[3])continue; dp[ac[i].next[k]->index][state+bit[k]]=max(dp[ac[i].next[k]->index][state+bit[k]],dp[i][state]+ac[i].next[k]->isword);
}
}
}
}
}
}
}
int ans=0;
int tag=cnt[0]*bit[0]+cnt[1]*bit[1]+cnt[2]*bit[2]+cnt[3]*bit[3];
for(int i=0;i<idx;i++)
ans=max(ans,dp[i][tag]);
return ans;
}
int main()
{
rev['A']=0;
rev['C']=1;
rev['G']=2;
rev['T']=3; int n,cas=1;
while(scanf("%d",&n)!=EOF && n)
{
idx=0;
trie *root = New();
for(int i=1;i<=n;i++)
{
scanf("%s",word);
Insert(root,word,strlen(word));
}
acbuild(root); scanf("%s",word);
int len=strlen(word);
memset(cnt,0,sizeof cnt);
for(int j=0;j<len;j++)
cnt[rev[word[j]]]++;
printf("Case %d: %d\n",cas++,solve());
}
return 0;
}
版权声明:本文博主原创文章。博客,未经同意不得转载。
Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)的更多相关文章
- HDU - 3341 Lost's revenge(AC自己主动机+DP)
Description Lost and AekdyCoin are friends. They always play "number game"(A boring game b ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- HDU - 4758 Walk Through Squares (AC自己主动机+DP)
Description On the beaming day of 60th anniversary of NJUST, as a military college which was Secon ...
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- hdu4758 Walk Through Squares (AC自己主动机+DP)
Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- poj 3691 DNA repair(AC自己主动机+dp)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5877 Accepted: 2760 Descri ...
- hdu4057 Rescue the Rabbit(AC自己主动机+DP)
Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU - 4511 小明系列故事――女友的考验(AC自己主动机+DP)
Description 最终放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候.女朋友告诉他.她在电影院等他,小明过来的路线必须满足给定的规则: 1.如果小明 ...
- Hdu 2457 DNA repair (ac自己主动机+dp)
题目大意: 改动文本串的上的字符,使之不出现上面出现的串.问最少改动多少个. 思路分析: dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...
随机推荐
- Mono和Jexus并且部署ASP.NET MVC3、4、5和WebApi
Linux(CentOS 6.7)下配置Mono和Jexus并且部署ASP.NET MVC3.4.5和WebApi(跨平台) 1.开篇说明 a. 首先我在写这篇博客之前,已经在自己本地配置了mono和 ...
- 利用json获取天气信息
天气预报信息获取是利用json获取的,网上有非常多资源,源码.因为上面涉及到非常多天气信息,包含湿度,出行建议等,以及加入了全部城市代码的资源包.为了练手了解json的原理.我仅获取诚笃城市的最高温, ...
- javascript面向对象程序设计
在学习js面向对象编程之前,首先须要知道什么是面向对象.面向对象语言都有类的概念,通过它能够创建具有同样属性和方法的对象.但js并没有类的概念,因此js中的对象和其它语言的对象有所不同. js对象能够 ...
- WeText项目的服务端
WeText项目的服务端 在<WeText项目:一个基于.NET实现的DDD.CQRS与微服务架构的演示案例>文章中,我介绍了自己用Visual Studio 2015(C# 6.0 wi ...
- hdu1876(dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1876 题意:问机器人到达终点的过程中最多有几次完全消耗完能量,消耗完这么多次能量的方式有几种. 分析: ...
- linux LNMP自动安装脚本
#!/bin/bashsoft_dir="/home/soft"config_dir="/home/config"httpd="httpd-2.0.5 ...
- SWT的TableVierer的使用二(数据排序)
有一个功能是我们常使用的,就是在列的头上点击一下,整个表的记录按照这个列来排序,再点击一下按照这个列的反序来排序.那JFace是如何实现这个功能的呢?在JFace中是通过一个排序器来实现的,就是Vie ...
- 也说Javascript对象拷贝及疑问
一.浅拷贝 当我们需要将一个对象拷贝至另一个对象时,我们一般会这么实现 function shadowCopy(source,target){ var target=target||{}; for(v ...
- Blob API及问题记录
接上一篇<js创建下载文件>, 记录核心部分 Blob 的API, >>传送门 , 同时说下使用过程中碰到的一个问题. 先说问题: 用Blob创建后缀为.sql的文件, 内容是 ...
- Multitasking Apps may only use background services for their intended purposes
2.16 Details Your app declares support for audio in the UIBackgroundModes key in your Info.plist, bu ...