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 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...
随机推荐
- Android消息循环分析
我们的经常使用的系统中,程序的工作一般是有事件驱动和消息驱动两种方式,在Android系统中,Java应用程序是靠消息驱动来工作的. 消息驱动的原理就是: 1. 有一个消息队列.能够往这个队列中投递消 ...
- JavaScript 中的事件类型1(读书笔记思维导图)
Web 浏览器中可能发生的事件有很多类型.如前所述,不同的事件类型具有不同的信息,而“ DOM3级事件”规定了以下几类事件. UI(User Interface,用户界面)事件:当用户与页面上的元素交 ...
- hdu1281+hdu2819(最大匹配数)
分析:将行和列缩点,即行对应二分图的X部,列对应二分图的Y部,然后交点为连接该行和该列的一条边.匹配时每点都会把整行整列占了,因此就不会出现冲突了. 传送门:hdu1281 棋盘游戏 #include ...
- Loser应该知道的6个残酷人生事实(血泪翻译)
Loser应该知道的6个残酷人生事实(血泪翻译) - Acfun - 天下漫友是一家 Loser应该知道的6个残酷人生事实(血泪翻译)
- android编译自己 内置的jar做法
1.首先 android.mk LOCAL_PATH := $(call my-dir) # ===================================================== ...
- 通过YAJL生成json语句
这里主要介绍的是怎样通过yajl生成一个json语句.方法通过代码就能够非常清楚的看到了,只是这里仅仅加入了字符串. 假设须要加入其它类型的,能够查考yajl的手冊,调用其它函数进行加入. /* * ...
- [Java聊天室server]实战之五 读写循环(服务端)
前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...
- C++ Primer 学习笔记_79_模板与泛型编程 --模板编译模型
模板与泛型编程 --模板编译模型 引言: 当编译器看到模板定义的时候,它不马上产生代码.仅仅有在用到模板时,假设调用了函数模板或定义了模板的对象的时候,编译器才产生特定类型的模板实例. 一般而言,当调 ...
- Shell 脚本常用命令
Shell脚本是Linux开发工作中常用的工具,但是我一直没有找到一个适合自己的简明扼要的HandBook.在工作过程中整理了一下,贴在这里已备查看. 1 Shell中的特殊符号 ...
- java 短信验证码===随机数
生成验证码,验证码生成 String mobile = phone;// 手机号码,多个号码使用","分割 // 生成随机6位码 String s = ""; ...