HDU-4057 Rescue the Rabbit(AC自动机+DP)
Rescue the Rabbit
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2036 Accepted Submission(s): 591
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.
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.
# include<iostream>
# include<cstdio>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std; const short N=1005;
const short INF=0x7fff; short ch[N][4];
short sz;
short val[N]; void init()
{
sz=0;
memset(ch,-1,sizeof(ch));
memset(val,0,sizeof(val));
} short idx(char c)
{
if(c=='A') return 0;
else if(c=='T') return 1;
else if(c=='C') return 2;
else if(c=='G') return 3;
} void insert(char *s,short x)
{
short r=0;
short n=strlen(s);
for(short i=0;i<n;++i){
short c=idx(s[i]);
if(ch[r][c]==-1) ch[r][c]=++sz;
r=ch[r][c];
}
val[r]=x;
} void getFail()
{
short *fail=new short[sz+1];
queue<short>q;
fail[0]=0;
for(short i=0;i<4;++i){
if(ch[0][i]==-1)
ch[0][i]=0;
else{
fail[ch[0][i]]=0;
q.push(ch[0][i]);
}
}
while(!q.empty())
{
short u=q.front();
q.pop();
val[u]|=val[fail[u]];
for(short i=0;i<4;++i){
if(ch[u][i]==-1)
ch[u][i]=ch[fail[u]][i];
else{
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
}
}
delete []fail;
} char s[6]; void solve(short n,short m,short *w)
{
short*** dp=new short**[2];
for(short i=0;i<2;++i){
dp[i]=new short*[sz+1];
for(short j=0;j<=sz;++j){
dp[i][j]=new short[1<<n];
}
} for(short i=0;i<=sz;++i) for(short j=0;j<(1<<n);++j)
dp[0][i][j]=-INF;
dp[0][0][0]=0;
short flag=1;
for(short i=0;i<m;++i,flag^=1){
for(short j=0;j<=sz;++j)
for(short k=0;k<(1<<n);++k)
dp[flag][j][k]=-INF;
for(short j=0;j<=sz;++j){
for(short k=0;k<(1<<n);++k){
if(dp[flag^1][j][k]==-INF)
continue;
for(short c=0;c<4;++c){
short v=ch[j][c];
short tempw=0;
for(short l=0;l<n;++l){
if(!(k&(1<<l))&&(val[v]&(1<<l)))
tempw+=w[l];
}
short &nxt=dp[flag][v][k|val[v]];
if(nxt<dp[flag^1][j][k]+tempw)
nxt=dp[flag^1][j][k]+tempw;
}
}
}
}
short ans=-INF;
for(short i=0;i<=sz;++i)
for(short j=0;j<(1<<n);++j)
ans=max(ans,dp[flag^1][i][j]);
if(ans>=0)
cout<<ans<<endl;
else
printf("No Rabbit after 2012!\n"); for(short i=0;i<2;++i){
for(short j=0;j<=sz;++j){
delete []dp[i][j];
}
delete []dp[i];
}
delete dp;
} int main()
{
short n,m;
while(cin>>n>>m)
{
init();
short *w=new short[n];
for(short i=0;i<n;++i){
scanf("%s%d",s,w+i);
insert(s,1<<i);
}
getFail();
solve(n,m,w);
delete []w;
}
return 0;
}
代码二:
# include<iostream>
# include<cstdio>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std; const int N=1005;
const int INF=0x7fff; int ch[N][4];
int sz;
int val[N]; void init()
{
sz=0;
memset(ch,-1,sizeof(ch));
memset(val,0,sizeof(val));
} int idx(char c)
{
if(c=='A') return 0;
else if(c=='T') return 1;
else if(c=='C') return 2;
else if(c=='G') return 3;
} void insert(char *s,int x)
{
int r=0;
int n=strlen(s);
for(int i=0;i<n;++i){
int c=idx(s[i]);
if(ch[r][c]==-1) ch[r][c]=++sz;
r=ch[r][c];
}
val[r]=x;
} void getFail()
{
int *fail=new int[sz+1];
queue<int>q;
fail[0]=0;
for(int i=0;i<4;++i){
if(ch[0][i]==-1)
ch[0][i]=0;
else{
fail[ch[0][i]]=0;
q.push(ch[0][i]);
}
}
while(!q.empty())
{
int u=q.front();
q.pop();
val[u]|=val[fail[u]];
for(int i=0;i<4;++i){
if(ch[u][i]==-1)
ch[u][i]=ch[fail[u]][i];
else{
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
}
}
delete []fail;
} char s[6];
int w[10];
int dp[2][N+1][1<<10]; int get(int s,int n)
{
int res=0;
for(int i=0;i<n;++i)
if(s&(1<<i)) res+=w[i];
return res;
} void solve(int n,int m)
{
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
int flag=1;
for(int i=0;i<m;++i,flag^=1){
memset(dp[flag],0,sizeof(dp[flag]));
for(int j=0;j<=sz;++j){
for(int k=0;k<(1<<n);++k) if(dp[flag^1][j][k]){
for(int c=0;c<4;++c)
dp[flag][ch[j][c]][k|val[ch[j][c]]]=1;
}
}
}
int ans=-INF;
for(int s=0;s<(1<<n);++s){
int temp=get(s,n);
for(int i=0;i<=sz;++i){
if(dp[flag^1][i][s]&&temp>ans){
ans=temp;
break;
}
}
}
if(ans>=0)
cout<<ans<<endl;
else
printf("No Rabbit after 2012!\n");
} int main()
{
int n,m;
while(cin>>n>>m)
{
init();
for(int i=0;i<n;++i){
scanf("%s%d",s,w+i);
insert(s,1<<i);
}
getFail();
solve(n,m);
}
return 0;
}
HDU-4057 Rescue the Rabbit(AC自动机+DP)的更多相关文章
- HDU 4057 Rescue the Rabbit(AC自动机+DP)
题目链接 一个数组开小了一点点,一直提示wa,郁闷,这题比上个题简单一点. #include <iostream> #include <cstring> #include &l ...
- HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )
模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...
- 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 ...
- HDU 2457 DNA repair(AC自动机+DP)题解
题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 4057 Rescue the Rabbit
题意 给出n(n<=10)个串,每个串有个权值,然后让你构造一个长度为l(l<=100)的串,如果他包含给出的串就得到相应的权值,求可能得到的最大权值 解法 AC自动机+DP,很显然要建立 ...
- HDU 4758 Walk Through Squares(AC自动机+DP)
题目链接 难得出一个AC自动机,我还没做到这个题呢...这题思路不难想,小小的状压出一维来,不过,D和R,让我wa死了,AC自动机,还得刷啊... #include<iostream> # ...
- HDU 2825 Wireless Password【AC自动机+DP】
给m个单词,由这m个单词组成的一个新单词(两个单词可以重叠包含)长度为n,且新单词中包含的基本单词数目不少于k个.问这样的新单词共有多少个? m很小,用二进制表示新单词中包含基本单词的情况. 用m个单 ...
- hdu4057Rescue the Rabbit(ac自动机+dp)
链接 当时是因为没有做出来这道题才开了自动机的专题,现在看看还是比较简单的. 因为每个病毒串只算一次,只有10个病毒串,可以状压一下哪些状态是可以达到的,最后取一个最大值. #include < ...
- 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 ...
随机推荐
- android editText 监听事件
在软键盘中注意 在监听的 edittext中 使用android:imeOptions属性的时候,一定要对EditText设置 android:inputType 或者 设置 android:sing ...
- Java_DOM创建XML
import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream; ...
- Oracle计算时间函数(对时间的加减numtodsinterval、numtoyminterval) (转)
原文来自:http://blog.itpub.net/756652/viewspace-697256/ 11g interval分区,按天分区,需要用到函数numtodsinterval. cre ...
- PHP 关于SQL注入的防范措施。
最近在使用框架的时候还是有点不安,不知道框架的设计者有没有考虑到SQL-Injection的问题,我在顶层需不需要做一些必要的过滤等等,由 此我特意的去StackOverflow看了下,真是获益良多, ...
- web 页面上纯js实现按钮倒计数功能
需求构思:本功能想实现的是,一个按钮在页面载入就显示提醒续费,,,倒数60秒后,完成提醒功能,可以按另外一个页面跳转到主页. 参考网上的大神,实现如下:Button2倒数,Button3跳转,在页面上 ...
- iOS---初识Swift(一)
一.Swift简介 ○ 2010年的夏天, 苹果公司的开发人员Chris Latten接到了一个特别的任务, 为OS X 和iOS平台开发下一代编程语言, 也就是Swift. ○ 苹果公司于2014年 ...
- php项目中使用memcache
memcache为分布式内存缓存系统,通过在内存中存取数据和对象减少对数据库的访问从而减轻数据库的负载,memcache分为客户端和服务端,服务端为C实现,有现成的服务端应用程序,无需开发,只需要配置 ...
- 部署Maven核心程序
1.安装Maven核心程序 1.1 检查JAVA_HOME环境变量 2. 解压Maven核心程序压缩包,放在一个非中文无空格的路径下 3. 配置Maven相关的环境变量 3.1 MAVEN_HOME ...
- kafka 订单应用需求
kafka的介绍就不说了,网上会找到一大堆. 为了公司做报表需要对卡券订单的销售情况做总结,所以每次下单的时候都要给卡券活动模块传递一次消息,并把订单的信息发送给活动,活动做相应的数据操作,因为数据量 ...
- 370. Range Addition
Assume you have an array of length n initialized with all 0's and are given k update operations. Eac ...