hdu 4057 Rescue the Rabbit
题意
给出n(n<=10)个串,每个串有个权值,然后让你构造一个长度为l(l<=100)的串,如果他包含给出的串就得到相应的权值,求可能得到的最大权值
解法
AC自动机+DP,很显然要建立自动机,然后在上面跑,如果不要求每个串的权值只能获取一次,那么直接跑来跑去的就行,但是因为只能取一次,串很少,可以状态压缩DP,dp[i][j][k]记录前i个字符走到j状态并且已经获得的串状态为k时的最优解。需要滚动数组优化空间--
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N = ;
const int inf = ~0u>>;
int hash[];
struct node{
node *ch[],*fail;
int mask;
void clear(){
for(int i = ;i < ;i++)ch[i] = NULL;fail = NULL;
mask = ;
}
};
node stk[N*];
bool dp[][N][];
int score[];
struct Trie{
node *root;int top;
node* newnode(){
node *p = &stk[top++];
p -> clear();
return p;
}
void init(){
top = ;
root = newnode();
}
void insert(char *s,int number){
node *p = root;int len = strlen(s);
for(int i = ;i < len;i++){
int id = hash[s[i]];
if(p -> ch[id] == NULL)
p -> ch[id] = newnode();
p = p -> ch[id];
}
p -> mask |= <<number;
}
void build(){
queue<node*> Q;
root -> fail = root;
for(int i = ;i < ;i++)
if(root -> ch[i] == NULL)
root -> ch[i] = root;
else{
Q.push(root -> ch[i]);
root -> ch[i] -> fail = root;
}
while(!Q.empty()){
node *p = Q.front();Q.pop();
for(int i = ;i < ;i++)
if(p -> ch[i] == NULL)
p -> ch[i] = p -> fail -> ch[i];
else{
Q.push(p -> ch[i]);
p -> ch[i] -> fail = p -> fail -> ch[i];
p -> ch[i] -> mask |= p -> ch[i] -> fail -> mask;
}
}
}
int solve(int len,int number){
memset(dp,,sizeof(dp));
dp[][][] = true;
for(int i = ;i <= len;i++){
memset(dp[i&],,sizeof(dp[i&]));
for(int j = ;j < top;j++){
node *cur = &stk[j];
for(int st = ;st < <<number;st++){
if(dp[(i+)&][j][st]){
for(int k = ;k < ;k++){
node *next = cur -> ch[k];
dp[i&][next - stk][st | next -> mask] = ;
}
}
}
}
}
int ans = -inf;
for(int i = ;i < top;i++)
for(int j = ;j < <<number;j++)
if(dp[len&][i][j]){
ans = max(ans,score[j]);
}
return ans;
}
};
Trie AC;
char s[N];
int w[];
int main(){
hash['A'] = ;hash['C'] = ;hash['G'] = ;hash['T'] = ;
int n,l;
int cas = ;
while(~scanf("%d%d",&n,&l)){
AC.init();
for(int i = ;i < n;i++){
scanf("%s%d",s,&w[i]);
AC.insert(s,i);
}
for(int i = ;i < <<n ;i++){
score[i] = ;
for(int j = ;j < n;j++)
if(i&(<<j))score[i] += w[j];
}
AC.build();
int ans = AC.solve(l,n);
//printf("Case %d\n",cas++);
if(ans < )puts("No Rabbit after 2012!");
else printf("%d\n",ans);
}
return ;
}
hdu 4057 Rescue the Rabbit的更多相关文章
- 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 ...
- 【HDOJ】4057 Rescue the Rabbit
挺有意思的一道题目,解法是AC自动机+DP.AC自动机建立fail指针时,一定要注意结点的属性也需要传递.AC自动机结合了trie和kmp的优点.需要注意的是,每个模式串仅计算一次,否则这题很难解. ...
- hdu4057 Rescue the Rabbit
地址:http://acm.hdu.edu.cn/showproblem.php?pid=4057 题目: Rescue the Rabbit Time Limit: 20000/10000 MS ( ...
- hdu 4057 AC自己主动机+状态压缩dp
http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...
- HDU-4057 Rescue the Rabbit(AC自动机+DP)
Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- HDU 1222 Wolf and Rabbit(gcd)
HDU 1222 Wolf and Rabbit (最大公约数)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid= ...
- hdu4057 Rescue the Rabbit(AC自己主动机+DP)
Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- JSOI2009 密码 和 JSOI2007 文本生成器 和 ZOJ3545 Rescue the Rabbit
密码 众所周知,密码在信息领域起到了不可估量的作用.对于普通的登陆口令,唯一的破解 方法就是暴力破解一逐个尝试所有可能的字母组合,但这是一项很耗时又容易被发现的工 作.所以,为了获取对方的登陆口令,在 ...
随机推荐
- select2宽度占比100%,导致无法实现浮动效果
- lodash中文说明文档
lodash中文说明文档 https://www.css88.com/doc/lodash/
- 用list去初始化numpy的array数组 numpy的array和python中自带的list之间相互转化
http://blog.csdn.net/baiyu9821179/article/details/53365476 a=([3.234,34,3.777,6.33]) a为python的list类型 ...
- vs2008控件查看器
使用 OLE/COM 对象查看器 通过读取控件的类型库,OLE/COM 对象查看器使您得以查看控件的接口. 使用 OLE/COM 对象查看器 单击“工具”菜单上的“OLE/COM 对象查看器”或在命令 ...
- P2257 YY的GCD (莫比乌斯反演)
题意:求\[\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j) = prim]\] 题解:那就开始化式子吧!! \[f(d) = \sum_{i=1}^{n}\sum_{j=1 ...
- 如何在windows 2008 IIS7 上实现AD域的访问控制
1.服务器加入域 2.创建点站 3.对站站进行设置 3.1设置网站的连接模式 选中站点,在控制台右侧 选择 基本设置 => 选择 应用程序用户 3.2 开启访问模式 选择站点 => 身份验 ...
- Spring boot 项目打成war包并在idea中运行
1. 修改pom文件原来是jar改成<packaging>war</packaging> 2. 在pom文件中添加移除内置tomcat并且添加添加servlet-api的依赖. ...
- Oracle中的for和while循环
实例: beginfor i in 51..500 loop delete from test t where t.date=to_date('2016-07-01', 'yyyy-MM-dd') a ...
- upupoo(网页壁纸)自主修改一:农历
最近在使用一款upupoo的壁纸软件,感觉还可以,主要是对其中html可设置为壁纸方面情有独钟 前几天在它的网页区发现了一个壁纸,感觉挺好: 感觉内容有点少,今天在工作空余时间就在其中加上了农历,同时 ...
- Xcode导入第三方库图文
Three20这个与facebook亲戚的开源库是蜚声iPhone开发界,很多App都有它的影子,主要是其真得是功能强大.那么如何将Three20库添加到自己的项目中应用呢?一种是Python命令方式 ...