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 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...
随机推荐
- 动态分析maillog日志,把恶意链接直接用防火墙禁止
近期用 postfix + dovecot 搭建了一个邮件server, 被人当做垃圾邮件转发器,经过配置postfix 的黑白名单, postfix 提示成功的 REJECT 了垃圾邮件, 只是还是 ...
- asp.net出现正在中止线程解决方案
刚才又再次遇到了一个之前遇到的问题,在这里记录一下. 起因: 如果使用 Response.End.Response.Redirect 或 Server.Transfer 方法,将出现 ThreadAb ...
- windows 2003 自动安全设置
@echo offecho.echo.echo.echo 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓echo.echo.echo windows 2003 自动安全设置程序 echo. ec ...
- HDU 1226 超级密码 (搜素)
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1226 题意简单,本来是一道很简单的搜素题目. 但是有两个bug: 1.M个整数可能有重复的. 2.N可 ...
- 【从翻译mos文章】正在实施的获取job的 session id
正在实施的获取job的 session id 参考原始: How to get the session Id of the Running Job (Doc ID 1604966.1) 申请: Ora ...
- hdu2036 (计算多边形的面积)
Input 输入数据包含多个测试实例,每个测试实例占一行,每行的开始是一个整数n(3<=n<=100),它表示多边形的边数(当然也是顶点数),然后是按照逆时针顺序给出的n个顶点的坐标(x1 ...
- hadoop在实现kmeans算法——一个mapreduce实施
写mapreduce程序实现kmeans算法.我们的想法可能是 1. 次迭代后的质心 2. map里.计算每一个质心与样本之间的距离,得到与样本距离最短的质心,以这个质心作为key,样本作为value ...
- WPF界面设计技巧(9)—使用UI自动化布局
原文:WPF界面设计技巧(9)-使用UI自动化布局 最近一直没时间更新这系列文章,因为我一直在埋头编写我的第一个WPF应用程序:MailMail 今天开始编写附属的加密/解密工具,对UI自动化布局有些 ...
- WPF换肤之七:异步
原文:WPF换肤之七:异步 在WinForm时代,相信大家都遇到过这种情形,如果在程序设计过程中遇到了耗时的操作,不使用异步会导致程序假死.当然,在WPF中,这种情况也是存在的,所以我们就需要寻找一种 ...
- Yii/Yii2:查询返回以某特定列为索引(键)的数组
在Yii1.x中,要想查询语句返回以特定列为键(key)的数组数据,代码例如以下(下述样例以表主键为返回数组索引): $users = User::model()->findAll(array( ...