您的位置:首页 > 产品设计 > UI/UE

hdu4057 Rescue the Rabbit【AC自动机+dp滚动数组】

2016-03-16 21:46 405 查看
Description

Dr. X is a biologist, who likes rabbits very much and can do everything for them. 2012 is coming, and Dr. X wants to take some rabbits to Noah's Ark, or there are no rabbits any more.

A rabbit's genes can be expressed as a string whose length is l (1 ≤ l ≤ 100) containing only 'A', 'G', 'T', 'C'. There is no doubt that Dr. X had a in-depth research on the rabbits' genes. He found that if a rabbit gene contained a particular gene segment,
we could consider it as a good rabbit, or sometimes a bad rabbit. And we use a value W to measure this index.

We can make a example, if a rabbit has gene segment "ATG", its W would plus 4; and if has gene segment "TGC", its W plus -3. So if a rabbit's gene string is "ATGC", its W is 1 due to ATGC contains both "ATG"(+4) and "TGC"(-3). And if another rabbit's gene string
is "ATGATG", its W is 4 due to one gene segment can be calculate only once.

Because there are enough rabbits on Earth before 2012, so we can assume we can get any genes with different structure. Now Dr. X want to find a rabbit whose gene has highest W value. There are so many different genes with length l, and Dr. X is not good at
programming, can you help him to figure out the W value of the best rabbit.

 

Input

There are multiple test cases. For each case the first line is two integers n (1 ≤ n ≤ 10),l (1 ≤ l ≤ 100), indicating the number of the particular gene segment and the length of rabbits' genes.

The next n lines each line contains a string DNAi and an integer wi (|wi| ≤ 100), indicating this gene segment and the value it can contribute to a rabbit's W.

 

Output

For each test case, output an integer indicating the W value of the best rabbit. If we found this value is negative, you should output "No Rabbit after 2012!".

 

Sample Input

2 4
ATG 4
TGC -3

1 6
TGC 4

4 1
A -1
T -2
G -3
C -4

 

Sample Output

4
4
No Rabbit after 2012!

Hint

case 1:we can find a rabbit whose gene string is ATGG(4), or ATGA(4) etc. case 2:we can find a rabbit whose gene string is TGCTGC(4), or TGCCCC(4) etc. case 3:any gene string whose length is 1 has a negative W.

 

这次的状态压缩dp实在是太难了QAQ 状压倒也是自己dp当中做的最次的啊==

说题意:DNA序列中给出某段对于总体的贡献值,可正可负,求n种子字符串可表示的m长度的字符串的最大值,-1单独输出

做这个题一定会想到:

hdu2825Wireless Password【ac自动机+dp状态压缩】

而且4057更难在了dp数组不仅第三维是二进制表示的,而且第一维也是滚动数组压缩的,dp的推到依旧没变,注意将ATGC转化成ABCD因为next数组是挨着的啊@。@ 然后注意是%2!!每步都是!!还有就是分数的计算,想了半天怎么累加分数,还想预处理来着,dp转移想半天没写出来,其实就是枚举每个二进制状态再遍历每一位,相加即可,再有就是struct的容量好像是根据最大的元素*个数算的吧,貌似牛客网上说过这题,所以kuangbin的模板就把struct删了就好,又因为queue的存在,next
end数组不可用,还得改名字,再有就是数组越界不一定会判RE,没准就是WA  其实这么看来,这个类型题也不是特别难啊

/***********
hdu4057
2016.3.16
1450MS 9800K 3338B C++
***********/
#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int score[110],dp[2][1005][1<<10];
int n,m,k;
int max(int a,int b){if(a>b)return a;return b;}
int nxt[1005][4],fail[1005],nd[1010];
int root,L;
int newnode()
{
for(int i=0;i<4;i++)nxt[L][i]=-1;
nd[L++]=0;
return L-1;
}
void init()
{
L=0;
root=newnode();
}
void insert(char buf[],int id)
{
int len=strlen(buf);
int now=root;
for(int i=0;i<len;i++)
{
if(nxt[now][buf[i]-'A']==-1)
nxt[now][buf[i]-'A']=newnode();
now=nxt[now][buf[i]-'A'];
}
nd[now]|=(1<<id);
}
void build()
{
queue<int>Q;
fail[root]=root;
for(int i=0;i<4;i++)
if(nxt[root][i]==-1)
nxt[root][i]=root;
else
{
fail[nxt[root][i]]=root;
Q.push(nxt[root][i]);
}
while(!Q.empty())
{
int now=Q.front();
Q.pop();
nd[now]|=nd[fail[now]];
for(int i=0;i<4;i++)
if(nxt[now][i]==-1)
nxt[now][i]=nxt[fail[now]][i];
else
{
fail[nxt[now][i]]=nxt[fail[now]][i];
Q.push(nxt[now][i]);
}
}
}
void solve()
{
// printf("L=%d\n",L);
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;///!!!
for(int i=0;i<n;i++)
{
memset(dp[(i+1)%2],0,sizeof(dp[(i+1)%2]));
for(int j=0;j<L;j++)
{
for(int k=0;k<(1<<m);k++)
{
if(dp[i%2][j][k]==0)continue;//!!
for(int x=0;x<4;x++)
{
int newi=(i+1)%2;
int newj=nxt[j][x];//!!
int newk=k|nd[newj];
dp[newi][newj][newk]=dp[i%2][j][k];
// printf("newi=%d newj=%d newk=%d dp=%d\n",newi,newj,newk,dp[newi][newj][newk]);
}
}
}
}
int cnt=-0xfffffff;
for(int j=0;j<L;j++)
{
for(int i=0;i<(1<<m);i++)
{
int ans=0;
if(!dp[n%2][j][i])continue;
for(int g=0;g<m;g++)
{
if(i&(1<<g)) ans+=score[g];
}
// printf("ans=%d\n",ans);
cnt=max(ans,cnt);
}
}
if(cnt<0)printf("No Rabbit after 2012!\n");
else printf("%d\n",cnt);
return ;
}

char buf[200];
int main()
{
// freopen("cin.txt","r",stdin);
while(~scanf("%d%d",&m,&n))
{
init();
for(int i=0;i<m;i++)
{
scanf("%s",buf);
for(int i=0;i<strlen(buf);i++)
{
if(buf[i]=='G')buf[i]='B';
if(buf[i]=='T')buf[i]='D';
}
scanf("%d",&score[i]);
insert(buf,i);
}
build();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: