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

  1. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  2. POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)

    题目链接:Censored! 解析:AC自己主动机 + 高精度 + 简单DP. 字符有可能会超过128.用map映射一下就可以. 中间的数太大.得上高精度. 用矩阵高速幂会超时,简单的DP就能解决时间 ...

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

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

  4. [AC自己主动机+状压dp] hdu 2825 Wireless Password

    题意: 给n.m,k ,再给出m个单词 问长度为n的字符串.至少在m个单词中含有k个的组成方案有多少种. 思路: 因为m最大是10,所以能够採取状压的思想 首先建立trie图,在每一个单词的结束节点标 ...

  5. Hdu 2243 考研路茫茫——单词情结 (AC自己主动机+矩阵)

    哎哟喂.中文题. . .不说题意了. 首先做过POJ 2778能够知道AC自己主动机是能够求出长度为L的串中不含病毒串的数量的. POJ 2778的大概思路就是先用全部给的病毒串建一个AC自己主动机. ...

  6. POJ 3691 &amp; 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: ...

  7. poj 2778 AC自己主动机 + 矩阵高速幂

    // poj 2778 AC自己主动机 + 矩阵高速幂 // // 题目链接: // // http://poj.org/problem?id=2778 // // 解题思路: // // 建立AC自 ...

  8. poj 3691 DNA repair(AC自己主动机+dp)

    DNA repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5877   Accepted: 2760 Descri ...

  9. [POJ 1204]Word Puzzles(Trie树暴搜&amp;AC自己主动机)

    Description Word puzzles are usually simple and very entertaining for all ages. They are so entertai ...

随机推荐

  1. 在VS2012中使用GitHub

    注册GitHub账号(DeanZhouLin) https://github.com/ 向GitHub中添加一个仓库(Test) *创建完成后,记录该仓库的地址:https://github.com/ ...

  2. 如何添加地图控件到Windows Phone 8的页面中

    原文 如何添加地图控件到Windows Phone 8的页面中 本主题介绍了各种方法来添加一个地图控件到Windows Phone 8的项目.该地图控件在Windows Phone的SDK 8.0的库 ...

  3. 【leetcode】Candy(python)

    题目要求的比它的邻居比自己奖励,因此,我们有最少一个多的.所有我们可以找到所有的坑,凹坑例如,存在以下三种情况. 找到全部的凹点后,我们就能够从凹点处開始向左右两个方向依次查找递增序列.当中每一个高的 ...

  4. java中取得上下文路径的方法

    1.request.getContextPath(); 获得web根的上下文环境 如 /tree tree是web项目的root context 2.可以在servlet的init方法里 String ...

  5. 一步一步学android之事件篇——触摸事件

    触摸事件顾名思义就是触摸手机屏幕触发的事件,当用户触摸添加了触摸事件的View时,就是执行OnTouch()方法进行处理,下面通过一个动态获取坐标的例子来学习OnTouchListener事件,效果如 ...

  6. struts2集成fckeditor(来自大型门户网站是这样练成的一书)

  7. 【ThinkingInC++】8、说明,浅谈数据类型的大小

    /** * 特征:说明.浅谈数据类型的大小 * 时刻:2014年8一个月10日本11:02:02 * 笔者:cutter_point */ #include<iostream> using ...

  8. Nutch+Lucene搜索引擎开发实践

    网络拓扑 图 1 网络拓扑图 安装Java JDK 首先查看系统是否已经安装了其它版本号的JDK,假设有,先要把其它版本号的JDK卸载. 用root用户登录系统. # rpm-qa|grep gcj ...

  9. 创Wcf案例数据服务

    首先,创建实体类: using System; using System.Linq; using System.Collections.Generic; using System.Data.Servi ...

  10. FileStream:The process cannot access the file because it is being used by another process

    先看下面一段代码(先以共享的方式打开文件读写,然后以只读的方式打开相同文件): FileStream fs  = new FileStream(filePath, FileMode.Open, Fil ...