题意

  给出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的更多相关文章

  1. HDU 4057 Rescue the Rabbit(AC自动机+DP)

    题目链接 一个数组开小了一点点,一直提示wa,郁闷,这题比上个题简单一点. #include <iostream> #include <cstring> #include &l ...

  2. HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )

    模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...

  3. 【HDOJ】4057 Rescue the Rabbit

    挺有意思的一道题目,解法是AC自动机+DP.AC自动机建立fail指针时,一定要注意结点的属性也需要传递.AC自动机结合了trie和kmp的优点.需要注意的是,每个模式串仅计算一次,否则这题很难解. ...

  4. hdu4057 Rescue the Rabbit

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=4057 题目: Rescue the Rabbit Time Limit: 20000/10000 MS ( ...

  5. hdu 4057 AC自己主动机+状态压缩dp

    http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...

  6. HDU-4057 Rescue the Rabbit(AC自动机+DP)

    Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. HDU 1222 Wolf and Rabbit(gcd)

    HDU 1222   Wolf and Rabbit   (最大公约数)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid= ...

  8. hdu4057 Rescue the Rabbit(AC自己主动机+DP)

    Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  9. JSOI2009 密码 和 JSOI2007 文本生成器 和 ZOJ3545 Rescue the Rabbit

    密码 众所周知,密码在信息领域起到了不可估量的作用.对于普通的登陆口令,唯一的破解 方法就是暴力破解一逐个尝试所有可能的字母组合,但这是一项很耗时又容易被发现的工 作.所以,为了获取对方的登陆口令,在 ...

随机推荐

  1. 浅谈p值(p-value是什么)

    当我们说到p-value时,我们在说什么? “这个变量的p-value小于0.05,所以这个变量很重要” ........ 你真的知道自己在说什么么???这个p-value到底是个什么鬼?为什么小于0 ...

  2. Xgboost集成算法

    集成算法思想: Xgboost基本原理: Xboost中是一个树(函数)接着一个树(函数)往里加,每加一个树都希望整体表达效果更好一些,即:目标函数逐步减小. 每加入一个函数,使目标函数逐渐减小,整体 ...

  3. 二分+贪心 || CodeForces 551C GukiZ hates Boxes

    N堆石头排成一列,每堆有Ai个石子.有M个学生来将所有石头搬走.一开始所有学生都在原点, 每秒钟每个学生都可以在原地搬走一块石头,或者向前移动一格距离,求搬走所有石头的最短时间. *解法:二分答案x( ...

  4. MySQL-07 日志管理

    学习目标 MySQL日志 二进制日志 错误日志 查询通用日志 慢查询日志 MySQL日志 MySQL日志分为四类,说明如下: 错误日志:记录MySQL服务的启动.运行或者停止时出现的问题. 查询日志: ...

  5. docker运行时设置redis密码并替换redis默认的dump.rdb

    docker run -itd --name test -p 6379:6379 -v /tmp/dump.rdb:/data/dump.rdb redis:4.0.8 --requirepass ' ...

  6. 错误的语法:"create view必须是批处理中仅有的语句"

    编写脚本提示: 错误的语法:"create view必须是批处理中仅有的语句" FROM sys.views WHERE name = 'v_CS_UserRoleNames' ) ...

  7. tcpdump抓包指令使用示例

    tcpdump是一个用于截取网络分组,并输出分组内容的工具. tcpdump凭借强大的功能和灵活的截取策略,使其成为类UNIX系统下用于网络分析和问题排查的首选工具.tcpdump提供了源代码,公开了 ...

  8. cobbler 无人值守-安装

    环境准备 准备两台主机,如centos6和centos7 centos7当作server服务器 关闭selinux 关闭防火墙 安装 cobbler包光盘里是没有的,要配置epel源,这里就说怎么配置 ...

  9. JavaScript基础对象---Number

    一.创建Number实例对象 /** * new Number(value); * value 被创建对象的数字值 * * Number 对象主要用于: 如果参数无法被转换为数字,则返回 NaN. 在 ...

  10. Nginx配置ThinkPHP和Laravel虚拟主机

    ThinkPHP server { listen 443 ssl; server_name abc.com; root /var/www/abc; ssl on; ssl_certificate /e ...