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
密码 众所周知,密码在信息领域起到了不可估量的作用.对于普通的登陆口令,唯一的破解 方法就是暴力破解一逐个尝试所有可能的字母组合,但这是一项很耗时又容易被发现的工 作.所以,为了获取对方的登陆口令,在 ...
随机推荐
- Python 循环结构语句
1.for循环:计次循环 2.while循环:条件循环 3.嵌套循环 4.跳转语句 一.for循环的使用 1.进行数值循环 利用数值循环输出三次‘你好’: >>> for i in ...
- lodash中文说明文档
lodash中文说明文档 https://www.css88.com/doc/lodash/
- 我的app自动化实战练习一
''' -*- coding: utf-8 -*- @Time : 2019/6/10 0010 10:39 @Author : 无邪 @File : test_data.py @Software: ...
- JavaEE-08 JSTL和EL
学习要点 EL表达式 JSTL标签 EL表达式 为什么需要EL表达式 JavaBean在JSP中的局限 在JSP页面中嵌入大量的Java代码 获取JavaBean属性必须要实例化 强制类型转化 例如, ...
- pytorch系列 -- 9 pytorch nn.init 中实现的初始化函数 uniform, normal, const, Xavier, He initialization
本文内容:1. Xavier 初始化2. nn.init 中各种初始化函数3. He 初始化 torch.init https://pytorch.org/docs/stable/nn.html#to ...
- More Effective C++ - 章节二 : 操作符(operators)
5. 对定制的 "类型转换函数" 保持警觉 允许编译器执行隐式类型转换,害处多过好处,不要提供转换函数,除非你确定需要. class foo { foo(int a = 0, in ...
- java多线程之ForkJoinPool
转https://www.cnblogs.com/lixuwu/p/7979480.html 阅读目录 使用 背景:ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任 ...
- pwntools各使用模块简介
pwntools pwntools 是一款专门用于CTF Exploit的python库,能够很方便的进行本地与远程利用的切换,并且里面包含多个模块,使利用变得简单.可以在github上直接搜索pwn ...
- POJ 2631 Roads in the North (求树的直径)
Description Building and maintaining roads among communities in the far North is an expensive busine ...
- POJ 1949 Chores(DAG上的最长路 , DP)
题意: 给定n项任务, 每项任务的完成用时t和完成每项任务前需要的k项任务, 求把所有任务完成的最短时间,有当前时间多项任务都可完成, 那么可以同时进行. 分析: 这题关键就是每项任务都会有先决条件, ...