【HDOJ】4057 Rescue the Rabbit
挺有意思的一道题目,解法是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的更多相关文章
- 【HDOJ】1222 Wolf and Rabbit
最大公约数,辗转相除. #include <stdio.h> long long gcd(long long a, long long b) { if (a<b) return gc ...
- 【HDOJ】1242 Rescue
BFS+优先级队列. #include <iostream> #include <cstdio> #include <cstring> #include <q ...
- 【HDOJ】4729 An Easy Problem for Elfness
其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...
- HDU 4057 Rescue the Rabbit(AC自动机+DP)
题目链接 一个数组开小了一点点,一直提示wa,郁闷,这题比上个题简单一点. #include <iostream> #include <cstring> #include &l ...
- 【HDOJ】【3506】Monkey Party
DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...
- 【HDOJ】【3516】Tree Construction
DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...
- 【HDOJ】【3480】Division
DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...
- 【HDOJ】【2829】Lawrence
DP/四边形不等式 做过POJ 1739 邮局那道题后就很容易写出动规方程: dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价) $w(l, ...
- 【HDOJ】【3415】Max Sum of Max-K-sub-sequence
DP/单调队列优化 呃……环形链求最大k子段和. 首先拆环为链求前缀和…… 然后单调队列吧<_<,裸题没啥好说的…… WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……s ...
随机推荐
- JDOM方法实现对XML文件的解析
首先要下载JDOM.jar包,下载地址:http://download.csdn.net/detail/ww6055/8880371 下载到JDOM.jar包之后导入到工程中去. 实例程序: book ...
- 用pelican搭建完美博客
前面有文章介绍本站采用了Python编写的Pelican静态生成博客系统, 之所以没有使用当前很火的Jekyll, 是因为它是Ruby编写, 而我又对Ruby没有啥兴趣, 所以还是选择了使用了我熟悉的 ...
- Redis多机集群
Redis集群.网上很多教程,只是按着它的步骤来做只能在单机上跑,而已不有点抗.也不用密码验证 开始: 1:redis集群最少需要要6个服务器端,因此先搞6台虚拟机 我用 centOS-7 mini ...
- Github上关于大数据的开源项目、论文等合集
https://github.com/onurakpolat/awesome-bigdata
- Raphael:JS矢量图形库
Raphael:JS矢量图形库 2016-08-29 http://dmitrybaranovskiy.github.io/raphael/
- iPad知识点记录
这两天玩了玩虚拟机安装Mac OS系统.iPad1的越狱以及利用iTunes将iPad2的系统升级到iOS8.1,这里将一些参考资源以及关键点记录一下. 一.虚拟机安装Mac OS 首先你的系统要能够 ...
- JAVA 修改 JSESSIONID
@Action("sidTest") public void sidTest() { HttpSession session = request.getSession(); Str ...
- tp数据表字段缓存
在维护一个tp写的项目,因为需要在产品表product中增加了一个字段status,但是不论如何就是无法给status赋值,查了资料才发现,原来是tp的数据表字段缓存在搞鬼. 在runtime> ...
- Delphi新语法和ifthen的扩展联想
Delphi之前已经重载了好多个ifthen函数 Math单元 ): Integer; overload; inline; ): Int64; overload; inline; ): UInt64; ...
- windows 系统下,小数据量Oracle用户物理备份
环境:windows Server 2003 oracle 10g,系统间备份 目标系统创建共享文件,原系统挂载共享目录 写批处理脚本,用任务计划定时调用 Rem * 由于系统实时性要求不是很高,数据 ...