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

 /* 4057 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int maxn = ;
const int maxm = ;
const int maxl = ;
char s[maxl];
int W[maxn];
bool dp[][maxm][maxm];
int n, m, l; typedef struct {
static const int maxn = ;
static const int rt = ;
int nxt[maxn][];
int fail[maxn];
int f[maxn];
int m; void init() {
m = ;
memset(f, , sizeof(f));
memset(nxt, , sizeof(nxt));
} int newNode() {
return ++m;
} int getId(char c) {
if (c == 'A') return ;
if (c == 'T') return ;
if (c == 'G') return ;
if (c == 'C') return ;
return -;
} void Insert(char *s, int k) {
int i = , id;
int p = , q; while (s[i]) {
id = getId(s[i]);
q = nxt[p][id];
if (!q)
q = nxt[p][id] = newNode();
p = q;
++i;
}
f[p] |= ( << k);
} void Build() {
int cur;
queue<int> Q; fail[rt] = rt;
rep(i, , ) {
if (nxt[rt][i] == ) {
nxt[rt][i] = rt;
} else {
fail[nxt[rt][i]] = rt;
Q.push(nxt[rt][i]);
}
} while (!Q.empty()) {
cur = Q.front();
Q.pop();
rep(i, , ) {
if (nxt[cur][i] == ) {
nxt[cur][i] = nxt[fail[cur]][i];
} else {
fail[nxt[cur][i]] = nxt[fail[cur]][i];
f[nxt[cur][i]] |= f[nxt[fail[cur]][i]];
Q.push(nxt[cur][i]);
}
}
}
} } AC; AC ac; int calw(int x) {
int ret = ; rep(i, , n) {
if (x & (<<i))
ret += W[i];
} return ret;
} void solve() {
int ans = INT_MIN;
int mst = <<n, nst, nxt;
int p = , q = ; m = ac.m;
memset(dp, , sizeof(dp));
dp[][ac.rt][] = true;
rep(i, , l+) {
memset(dp[q], , sizeof(dp[q]));
rep(j, , m+) {
rep(k, , ) {
rep(st, , mst) {
if (dp[p][j][st]) {
nxt = ac.nxt[j][k];
nst = st | ac.f[nxt];
dp[q][nxt][nst] = true;
}
}
}
}
p = q;
q ^= ;
} rep(st, , mst) {
rep(j, , m+) {
if (dp[p][j][st]) {
ans = max(ans, calw(st));
break;
}
}
} if (ans < )
puts("No Rabbit after 2012!");
else
printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int len, w; while (scanf("%d %d",&n,&l) != EOF) {
ac.init();
rep(i, , n) {
scanf("%s %d", s, &W[i]);
ac.Insert(s, i);
} ac.Build();
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

【HDOJ】4057 Rescue the Rabbit的更多相关文章

  1. 【HDOJ】1222 Wolf and Rabbit

    最大公约数,辗转相除. #include <stdio.h> long long gcd(long long a, long long b) { if (a<b) return gc ...

  2. 【HDOJ】1242 Rescue

    BFS+优先级队列. #include <iostream> #include <cstdio> #include <cstring> #include <q ...

  3. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

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

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

  5. 【HDOJ】【3506】Monkey Party

    DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...

  6. 【HDOJ】【3516】Tree Construction

    DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...

  7. 【HDOJ】【3480】Division

    DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...

  8. 【HDOJ】【2829】Lawrence

    DP/四边形不等式 做过POJ 1739 邮局那道题后就很容易写出动规方程: dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价) $w(l, ...

  9. 【HDOJ】【3415】Max Sum of Max-K-sub-sequence

    DP/单调队列优化 呃……环形链求最大k子段和. 首先拆环为链求前缀和…… 然后单调队列吧<_<,裸题没啥好说的…… WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……s ...

随机推荐

  1. ### 线性回归(Regression)

    linear regression logistic regression softmax regression #@author: gr #@date: 2014-01-21 #@email: fo ...

  2. JavaScript学习笔记(3)——JavaScript与HTML的组合方式

    一.JavaScript可以写在HTML页面内部, 可位于 HTML 的 <body> 或 <head> 部分中,或者同时存在于两个部分中. 通常的做法是把函数放入 <h ...

  3. C# ACM poj1008

    玛雅历 public static void Acm1008(int day, string mon, int year) { ; switch (mon) { case "pop" ...

  4. 基础之ThreadStatic

    public class Bean { public Bean() { } public static String Current { get { if (guid == null) guid = ...

  5. TLF相关资料

    1\(转)http://blog.csdn.net/hu36978/article/details/5796165 TFL 一般先创建TextFlow  通过控制flowComposer属性来控制文本 ...

  6. windows 安装 setuptools

    在python的网站上 : https://pypi.python.org/pypi/setuptools/ 查找windows,显不如下: 点击 ez_setup.py进入, 并将内容复制下来, 保 ...

  7. 七牛云覆盖上传 php

    使用七牛云过程中遇到了需要上传覆盖的情况,最终解决,分享给大家. 七牛云sdk上传示例中是这样写的 <?php require_once 'path_to_sdk/vendor/autoload ...

  8. Linux FTP服务安装和远程登录失败

    问题:本机VPlayer安装pure-ftpd  ftp服务,通过flashfxp从windows连接出现以下错误: [左] 正在连接到 vmare -> IP=192.168.174.133 ...

  9. ASP.NET输入文本框自动提示功能

    在ASP.NET Web开发中会经常用到自动提示功能,比如百度搜索.我们只要输入相应的关键字,就可以自动得到相似搜索关键字的提示,方便我们快速的输入关键字进行查询. 那么在ASP.NET中,如果我们需 ...

  10. 《Nodejs开发加密货币》之二十七:开发通用的HTML组件

    人的懒惰常常是麻烦的开始.多数程序员都希望自己的工作一劳永逸,一次开发,到处使用,成了人人追逐的目标,我也不例外.最初写<Nodejs开发加密货币>系列文章,因为不喜欢设定好了去写,所以目 ...