题意

  给出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. docker之启动创建容器流程

    libcontainer的工作流程 execdriver的run方法通过docker daemon提交一份command信息创建了一份可供libcontainer解读的容器配置container,继而 ...

  2. PHP18 PHP与AJAX

    学习要点 JavaScript实现Ajax jQuery实现Ajax JSON PHP的JSON函数 JavaScript处理JSON数据 JavaScript实现Ajax 什么是Ajax 搜狗地图 ...

  3. EBS ORACLE使用API批量取消销售订单

    需要切换组织,还有用户的id.下面红色字体代表要修改的地方. /*BEGIN MO_GLOBAL.INIT('M'); MO_GLOBAL.set_policy_context ('S',); FND ...

  4. sqlserver差异备份3117

    1.出现错误"3117" 2.完整备份/选项/不对数据库执行任何操作 3.数据库显示"正在还原" 4.差异备份/选项/回滚 5.数据库完整备份与差异备份成功

  5. CSS3---变形与动画效果

    1.旋转rotate()函数通过指定的角度参数使元素相对原点进行旋转.它主要在二维空间内进行操作,设置一个角度值,用来指定旋转的幅度.如果这个值为正值,则元素相对原点中心顺时针旋转:如果这个值为负值, ...

  6. 条款19:设计class犹如设计TYPE(Treat class design as type design)

    NOTE: 1.Class 的设计就是type的设计.在定义一个新type之前,请确认自己已经考虑过本条款所有主题(具体参考effective c++).

  7. 杭电 4004 The Frog's Games 青蛙跳水 (二分法,贪心)

    Description The annual Games in frogs' kingdom started again. The most famous game is the Ironfrog T ...

  8. react 语法细节总结说明

    1.当要获取某个数据列表中的某个字段时,用“.”附加的形式.例如:获取user中的balance字段,用this.props.user.balance 来表示. 2.当要打印某个数据或字段结果时,co ...

  9. captcha库报错"OSError: cannot open resource"

    问题描述 在win平台上python虚拟环境下使用captcha库生成验证码报错OSError: cannot open resource 代码 from captcha.image import I ...

  10. 楼房重建(bzoj 2957)

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...