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. sha1加密java代码

    sha1 加密 java代码 public static String getSha1(String str){ if(str==null||str.length()==0){ return null ...

  2. Android应用开发-小巫CSDN博客client之显示博文具体内容

    Android应用开发-小巫CSDN博客客户端之显示博文具体内容 上篇博文给大家介绍的是怎样嵌入有米广告而且获取收益,本篇博客打算讲讲关于怎样在一个ListView里显示博文的具体信息.这个可能是童鞋 ...

  3. C++转让Lua

    转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/39756423 我使用的cocos2d-x版本号是2.3.3.先在一个C++projec ...

  4. 很多人都在埋怨没有遇到好的团队,但好的团队不可能凭空出现,一流的团队不能仅靠团队成员努力,作为Leader,要有可行的规划,并坚定地执行、时势地调整(转)

    <西游记>中的唐僧团队历经千难万险,终于求得真经,目标明确.分工合理为这支队伍最终走向成功奠定了基础.唐僧从一开始,就为这个团队设定了西天取经的目标,虽然经历各种挫折与磨难,但目标从未动摇 ...

  5. [Windows]_[0基础]_[使用命令行工具dumpbin分析文件]

    dumpbin(vs拥有) 1. 出口lib函数符号文件(symbols) dumpbin /exports zlib1.lib Microsoft (R) COFF/PE Dumper Versio ...

  6. 《HBase权威指南》读书笔记----简介

    工作中要使用HBase,刚刚开始接触HBase,理解不深,只是记录一下 . HBase基于google的bigtable论文实现,属于nosql. 几个概念: (1)列(column):最基本单位为列 ...

  7. EasyUI基础searchbox&amp;progressbar(搜索框,进度条)

    easyui学习的基本组成部分(八个部分)硕果仅存searchbox和pargressbar.tooltip该,有一点兴奋.本文将偏向searchbox和pargressbar做一个探讨.鉴于双方的内 ...

  8. OpenStack Dashboard

    OpenStackDashboard 为管理员和普通用户提供了一个图形化管理界面.用户能够通过该界面訪问.分配或者自己主动化分配基于云的资源.可扩展的设计使得与第三方产品和服务融合变得非常easy,比 ...

  9. LeetCode: Multiply Strings. Java

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  10. Codeforces 484E Sign on Fence(是持久的段树+二分法)

    题目链接:Codeforces 484E Sign on Fence 题目大意:给定给一个序列,每一个位置有一个值,表示高度,如今有若干查询,每次查询l,r,w,表示在区间l,r中, 连续最长长度大于 ...