ZOJ3545 Rescue the Rabbit
分析
未知定长串中不同已知模板串的出现次数问题,一般做法是AC自动机上dp。
考虑背包,\(dp(i,j,k)\)表示当前串长为\(i\),在AC自动机上对应节点\(j\),已匹配的模板串的状态为\(k\)的情况是否出现。用刷表法向后转移。先枚举不定串长度,再枚举AC自动机上节点,然后枚举已知状态,最后枚举字母边转移。
时间复杂度\(O(l \cdot MaxNode \cdot 2^n \cdot SigmaSize)\)。第一维可以滚动,空间复杂度\(O(MaxNode \cdot 2^n)\)
代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x){
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;
const int MAXN=1010;
const int SigmaSize=4;
bool dp[2][MAXN][1100];
int mp[15];
struct Trie
{
int next[MAXN][SigmaSize];
int fail[MAXN];
int end[MAXN];
int root,ncnt;
int newnode()
{
for(int i=0;i<SigmaSize;++i)
next[ncnt][i]=-1;
end[ncnt++]=0;
return ncnt-1;
}
void init()
{
ncnt=0;
root=newnode();
}
int id(char c)
{
if(c=='A')
return 0;
else if(c=='G')
return 1;
else if(c=='T')
return 2;
else
return 3;
}
void insert(char*str,int v)
{
int now=root;
int len=strlen(str);
for(int i=0;i<len;++i)
{
int c=id(str[i]);
if(next[now][c]==-1)
next[now][c]=newnode();
now=next[now][c];
}
end[now]|=(1<<v);
}
void getfail()
{
queue<int>Q;
fail[root]=root;
for(int i=0;i<SigmaSize;++i)
{
if(next[root][i]==-1)
next[root][i]=root;
else
{
fail[next[root][i]]=root;
Q.push(next[root][i]);
}
}
while(!Q.empty())
{
int now=Q.front();
Q.pop();
end[now]|=end[fail[now]];
for(int i=0;i<SigmaSize;++i)
{
if(next[now][i]==-1)
next[now][i]=next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
}
void solve(int n,int l)
{
memset(dp,0,sizeof(dp));
dp[0][0][0]=1; // dp[len][node][state]
int cur=1;
for(int i=1;i<=l;++i)
{
memset(dp[cur],0,sizeof(cur));
for(int j=0;j<ncnt;++j)
{
for(int k=0;k<(1<<n);++k)
{
for(int q=0;q<SigmaSize;++q)
{
int nxt=next[j][q];
dp[cur][nxt][k|end[nxt]]=(dp[cur][nxt][k|end[nxt]]||dp[cur^1][j][k]);
}
}
}
cur^=1;
}
int ans=-INF;
for(int i=0;i<ncnt;++i)
for(int j=0;j<(1<<n);++j)
{
if(dp[cur^1][i][j])
{
int sum=0;
for(int k=0;k<n;++k)
if(j&(1<<k))
sum+=mp[k];
ans=max(ans,sum);
}
}
if(ans<0)
printf("No Rabbit after 2012!\n");
else
printf("%d\n",ans);
}
}AC;
char s[110];
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n,l,w;
while(~scanf("%d %d",&n,&l))
{
AC.init();
for(int i=0;i<n;++i)
{
scanf("%s %d",s,&w);
AC.insert(s,i);
mp[i]=w;
}
AC.getfail();
AC.solve(n,l);
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
ZOJ3545 Rescue the Rabbit的更多相关文章
- JSOI2009 密码 和 JSOI2007 文本生成器 和 ZOJ3545 Rescue the Rabbit
密码 众所周知,密码在信息领域起到了不可估量的作用.对于普通的登陆口令,唯一的破解 方法就是暴力破解一逐个尝试所有可能的字母组合,但这是一项很耗时又容易被发现的工 作.所以,为了获取对方的登陆口令,在 ...
- HDU-4057 Rescue the Rabbit(AC自动机+DP)
Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu4057 Rescue the Rabbit
地址:http://acm.hdu.edu.cn/showproblem.php?pid=4057 题目: Rescue the Rabbit Time Limit: 20000/10000 MS ( ...
- hdu4057 Rescue the Rabbit(AC自己主动机+DP)
Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU4057 Rescue the Rabbit(AC自动机+状压DP)
题目大概是给几个DNA片段以及它们各自的权值,如果一个DNA包含某个片段那么它的价值就加上这个片段的权值,同时包含多个相同DNA片段也只加一次,问长度l的DNA可能的最大价值. 与HDU2825大同小 ...
- HDU 4057 Rescue the Rabbit(AC自动机+DP)
题目链接 一个数组开小了一点点,一直提示wa,郁闷,这题比上个题简单一点. #include <iostream> #include <cstring> #include &l ...
- ZOJ 3545 Rescue the Rabbit(AC自动机+状压DP)(The 2011 ACM-ICPC Asia Dalian Regional Contest)
Dr. X is a biologist, who likes rabbits very much and can do everything for them. 2012 is coming, an ...
- 【HDOJ】4057 Rescue the Rabbit
挺有意思的一道题目,解法是AC自动机+DP.AC自动机建立fail指针时,一定要注意结点的属性也需要传递.AC自动机结合了trie和kmp的优点.需要注意的是,每个模式串仅计算一次,否则这题很难解. ...
- Zoj 3545 Rescue the Rabbit(ac自己主动机+dp)
标题效果: 鉴于DNA有一个正确的顺序值.请构造一个长度I的DNA在这个序列使DNA正确的顺序值极大.它被认为是负的输出噼啪. .. IDEAS: 施工顺序是,ac己主动机上走,求最大要用到dp dp ...
随机推荐
- 笔试题-sql语句
今天遇到了不熟练(不会)的查询题目 回来自己又做了一下,如下 建表语句 -- Table structure for score -- ---------------------------- DRO ...
- [可能没有默认的字体]Warning: imagettfbbox() [function.imagettfbbox]: Invalid font filename...
Warning: imagettfbbox() [function.imagettfbbox]: Invalid font filename... [可能没有默认的字体] 例: //putenv('G ...
- [.NET开发] C#连接MySQL的两个简单代码示例
实现代码一.使用的是mysql自带的驱动安装一下即可 这是一个简单的例子. 在这里有个问题:dataset如果没设主键的话,可能会引起一些对数库操作的问题,比如会造成updata出现错误. stati ...
- [Java代码] Java是自学好还是参加培训班好?
ava 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言. Java可运行于多个平台,如Windows, Mac OS,及其他多种UNIX版本的系统. 本教程给大家简单介 ...
- spring boot 基础篇 -- 自带图片服务器
我们平时在日常项目中经常会遇到图片的上传和访问的情景,平时我们可能习惯于把图片传到resource或者项项目中的某个位置,这样会有一个缺点,当我们重新项目打包时,这些图片会丢失.为了解决这一缺点,我们 ...
- 一篇关于oracle psu的文章(转)
Oracle Database PSU/CPU Posted on 2011-07-28 16:27 dbblog 阅读(2569) 评论(0) 编辑 收藏 1. 什么是PSU/CPU?CPU: Cr ...
- shiro中OAuth2 集成
OAuth 角色 资源拥有者(resource owner): 能授权访问受保护资源的一个实体,可以是一个人,那我们称之为最终用户:如新浪微博用户 zhangsan: 资源服务器(resource s ...
- kill word out 1
1● de 使~~ 成为 :离开 ,去掉,向下,变慢 2● dif 不,分开 ,否定,离开 3● deci 十分之一 4● deca 向下,离开 5● deca 十 6● di ...
- 安装完DevExpress14.2.5,如何破解它呢?
DevExpress是一个界面控件套件,提供了一系列的界面控件套件的DotNet界面控件.DevExpress开发的控件有很强的实力,不仅功能丰富,应用简单,而且界面华丽,更可方便订制,方便开发人员开 ...
- Integer封装类的相关知识
java中,在一些情况下会有自动装箱与自动拆箱. 自动拆箱/装箱是在编译期,依据代码的语法,决定是否进行拆箱和装箱动作.装箱过程:把基本类型用它们对应的包装类型进行包装,使基本类型具有对象特征.拆箱过 ...