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 ...
随机推荐
- 在一台机器上模拟mongodb分片
首先选择一个目录在其中建立以下2个文件夹:data和log 在data下建立9个文件夹: 其中前3个为配置服务器所在文件夹,按照官网要求,一个集群需要3个config server rs-a-n和rs ...
- eclipse 导入工程报错Unable to execute dex: Multiple dex files define Landroid/annotation/SuppressLint
对策: 检查libs 是否有重复加载的.
- Dapper学习笔记(2)-链接引用
在研究Dapper源码时发现Dapper NET45类库中的SqlMapper.cs文件前面有个蓝色的箭头图标,发现在Dapper NET45文件夹下根本不存在SqlMapper.cs文件,其文件属性 ...
- [C++中级进阶]001_C++0x里的完美转发到底是神马?
[C++中级进阶]001_C++0x里的完美转发到底是神马? 转载至:http://www.cnblogs.com/alephsoul-alephsoul/archive/2013/01/10/285 ...
- WebView---Android与js交互实例
Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true 原文地址:http://blog.csdn.net/it10 ...
- 快速了解IOC的几种姿势
一.首先我们了解IOC如何注入的几种姿势 构造函数注入(Constructor Injection) Ioc容器会智能的选择和调用合适的构造函数以创建依赖的对象.如果被选择的构造函数具有相应的参数,I ...
- jquery自定义插件——以 选项卡插件为例
一直打算尝试自定义插件,终于付诸实践了,现在把内容发表出来,与大家共勉. 我是根据自己正在用的插件,模仿其源码,实现的自定义插件,完成之后,在网上看相关资料,对自定义插件部分,有了更明确的认识. jq ...
- Excel的python读写
实际工作中可能需要整理一些文档,或者记录一些数据,这时候使用python来操作Excel可能会帮得上你. 读操作: # encoding : utf-8 #设置编码方式 import xlrd #导入 ...
- window10的优缺点
windows10的体验随笔 为了体验科技前沿,前段时间升级了windows10 优点: 首先换了windows10就回不去了, 1.开始菜单的回归是众向所归,而且也加了迷你的一些菜单元素,值得称 ...
- ibatis
ibatis学习笔记(一)>>>>>>>sqlMapConfig.xml文件详解 1.sqlMapConfig.xml配置文件详解: Xml代码 1. < ...