poj 1699 Best Sequence(AC自己主动机+如压力DP)
id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence
题目大意;给定N个DNA序列,问说最少多长的字符串包括全部序列。
解题思路:AC自己主动机+状压DP,先对字符串构造AC自己主动机。然后在dp[s][i]表示匹配了s。移动到节点i时候的最短步数。
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii;
const int maxn = 205;
const int sigma_size = 4;
const int inf = 0x3f3f3f3f;
struct Aho_Corasick {
int sz, g[maxn][sigma_size];
int tag[maxn], fail[maxn], last[maxn];
int dp[maxn][1030];
void init();
int idx(char ch);
void insert(char* str, int k);
void getFail();
void match(char* str);
void put(int x, int y);
int solve();
}AC;
int N;
char w[30];
int main () {
int cas;
scanf("%d", &cas);
while (cas--) {
AC.init();
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%s", w);
AC.insert(w, i);
}
printf("%d\n", AC.solve());
}
return 0;
}
int Aho_Corasick::solve() {
getFail();
memset(dp, inf, sizeof(dp));
dp[0][0] = 0;
queue<pii> que;
que.push(make_pair(0, 0));
while(!que.empty()) {
int u = que.front().first;
int s = que.front().second;
que.pop();
for (int i = 0; i < 4; i++) {
int k = u;
while (k && g[k][i] == 0)
k = fail[k];
k = g[k][i];
int ss = s | tag[k];
if (dp[k][ss] > dp[u][s] + 1) {
dp[k][ss] = dp[u][s] + 1;
que.push(make_pair(k, ss));
if (ss == (1<<N)-1)
return dp[k][ss];
}
}
}
return 0;
}
void Aho_Corasick::init() {
sz = 1;
tag[0] = 0;
memset(g[0], 0, sizeof(g[0]));
}
int Aho_Corasick::idx(char ch) {
if (ch == 'A')
return 0;
if (ch == 'C')
return 1;
if (ch == 'G')
return 2;
return 3;
}
void Aho_Corasick::put(int x, int y) {
}
void Aho_Corasick::insert(char* str, int k) {
int u = 0, n = strlen(str);
for (int i = 0; i < n; i++) {
int v = idx(str[i]);
if (g[u][v] == 0) {
tag[sz] = 0;
memset(g[sz], 0, sizeof(g[sz]));
g[u][v] = sz++;
}
u = g[u][v];
}
tag[u] |= (1<<k);
}
void Aho_Corasick::match(char* str) {
int n = strlen(str), u = 0;
for (int i = 0; i < n; i++) {
int v = idx(str[i]);
while (u && g[u][v] == 0)
u = fail[u];
u = g[u][v];
if (tag[u])
put(i, u);
else if (last[u])
put(i, last[u]);
}
}
void Aho_Corasick::getFail() {
queue<int> que;
for (int i = 0; i < sigma_size; i++) {
int u = g[0][i];
if (u) {
fail[u] = last[u] = 0;
que.push(u);
}
}
while (!que.empty()) {
int r = que.front();
que.pop();
for (int i = 0; i < sigma_size; i++) {
int u = g[r][i];
if (u == 0) {
g[r][i] = g[fail[r]][i];
continue;
}
que.push(u);
int v = fail[r];
while (v && g[v][i] == 0)
v = fail[v];
fail[u] = g[v][i];
tag[u] |= tag[fail[u]];
//last[u] = tag[fail[u]] ?
fail[u] : last[fail[u]];
}
}
}
版权声明:本文博主原创文章,博客,未经同意不得转载。
poj 1699 Best Sequence(AC自己主动机+如压力DP)的更多相关文章
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)
题目链接:Censored! 解析:AC自己主动机 + 高精度 + 简单DP. 字符有可能会超过128.用map映射一下就可以. 中间的数太大.得上高精度. 用矩阵高速幂会超时,简单的DP就能解决时间 ...
- hdu 4057 AC自己主动机+状态压缩dp
http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...
- [AC自己主动机+状压dp] hdu 2825 Wireless Password
题意: 给n.m,k ,再给出m个单词 问长度为n的字符串.至少在m个单词中含有k个的组成方案有多少种. 思路: 因为m最大是10,所以能够採取状压的思想 首先建立trie图,在每一个单词的结束节点标 ...
- Hdu 2243 考研路茫茫——单词情结 (AC自己主动机+矩阵)
哎哟喂.中文题. . .不说题意了. 首先做过POJ 2778能够知道AC自己主动机是能够求出长度为L的串中不含病毒串的数量的. POJ 2778的大概思路就是先用全部给的病毒串建一个AC自己主动机. ...
- POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...
- poj 2778 AC自己主动机 + 矩阵高速幂
// poj 2778 AC自己主动机 + 矩阵高速幂 // // 题目链接: // // http://poj.org/problem?id=2778 // // 解题思路: // // 建立AC自 ...
- poj 3691 DNA repair(AC自己主动机+dp)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5877 Accepted: 2760 Descri ...
- [POJ 1204]Word Puzzles(Trie树暴搜&AC自己主动机)
Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...
随机推荐
- 在VS2012中使用GitHub
注册GitHub账号(DeanZhouLin) https://github.com/ 向GitHub中添加一个仓库(Test) *创建完成后,记录该仓库的地址:https://github.com/ ...
- 如何添加地图控件到Windows Phone 8的页面中
原文 如何添加地图控件到Windows Phone 8的页面中 本主题介绍了各种方法来添加一个地图控件到Windows Phone 8的项目.该地图控件在Windows Phone的SDK 8.0的库 ...
- 【leetcode】Candy(python)
题目要求的比它的邻居比自己奖励,因此,我们有最少一个多的.所有我们可以找到所有的坑,凹坑例如,存在以下三种情况. 找到全部的凹点后,我们就能够从凹点处開始向左右两个方向依次查找递增序列.当中每一个高的 ...
- java中取得上下文路径的方法
1.request.getContextPath(); 获得web根的上下文环境 如 /tree tree是web项目的root context 2.可以在servlet的init方法里 String ...
- 一步一步学android之事件篇——触摸事件
触摸事件顾名思义就是触摸手机屏幕触发的事件,当用户触摸添加了触摸事件的View时,就是执行OnTouch()方法进行处理,下面通过一个动态获取坐标的例子来学习OnTouchListener事件,效果如 ...
- struts2集成fckeditor(来自大型门户网站是这样练成的一书)
- 【ThinkingInC++】8、说明,浅谈数据类型的大小
/** * 特征:说明.浅谈数据类型的大小 * 时刻:2014年8一个月10日本11:02:02 * 笔者:cutter_point */ #include<iostream> using ...
- Nutch+Lucene搜索引擎开发实践
网络拓扑 图 1 网络拓扑图 安装Java JDK 首先查看系统是否已经安装了其它版本号的JDK,假设有,先要把其它版本号的JDK卸载. 用root用户登录系统. # rpm-qa|grep gcj ...
- 创Wcf案例数据服务
首先,创建实体类: using System; using System.Linq; using System.Collections.Generic; using System.Data.Servi ...
- FileStream:The process cannot access the file because it is being used by another process
先看下面一段代码(先以共享的方式打开文件读写,然后以只读的方式打开相同文件): FileStream fs = new FileStream(filePath, FileMode.Open, Fil ...