DNA Sequence

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

思路:推荐一个博客,讲的很清楚。

这样的题目。n非常大,首先想到的就是用矩阵来优化。那么怎样构造转移方程呢:首先建立一棵Trie,然后依照AC自己主动机的方式构造fail指针,然后会发现。当一个状态分别加入ACTG之后,会得到还有一个状态。

(详细解释见代码)



代码:
/*
ID: wuqi9395@126.com
PROG:
LANG: C++
*/
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<fstream>
#include<cstring>
#include<ctype.h>
#include<iostream>
#include<algorithm>
#define INF (1<<30)
#define PI acos(-1.0)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, n) for (int i = 0; i < n; i++)
#define debug puts("===============")
typedef long long ll;
using namespace std;
const int maxn = 110;
const int maxm = 110;
ll mod = 100000;
struct Matrix {
int n, m;
ll a[maxn][maxm];
void clear() {
n = m = 0;
memset(a, 0, sizeof(a));
}
Matrix operator * (const Matrix &b) const { //实现矩阵乘法
Matrix tmp;
tmp.clear();
tmp.n = n;
tmp.m = b.m;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
if (!a[i][j]) continue;
for (int k = 0; k < b.m; k++)
tmp.a[i][k] += a[i][j] * b.a[j][k], tmp.a[i][k] %= mod;
} return tmp;
}
}A, res; const int maxnode = 11 * 11;
const int charset = 4;
struct ACAutomaton {
int ch[maxnode][charset];
int fail[maxnode];
int Q[maxnode];
int val[maxnode];
int sz;
int id(char ch) {
if (ch == 'A') return 0;
else if (ch == 'C') return 1;
else if (ch == 'T') return 2;
return 3;
}
void init() {
fail[0] = 0;
//for (int i = 0; i < charset; i++) ID[i] = i;
}
void reset() {
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
void Insert(char* s, int key) {
int u = 0;
for (; *s; s++) {
int c = id(*s);
if (!ch[u][c]) {
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = key;
}
void Construct () {
int *s = Q, *e = Q;
for (int i = 0; i < charset; i++) {
if (ch[0][i]) {
*e++ = ch[0][i];
fail[ch[0][i]] = 0;
}
}
while(s != e) {
int u = *s++;
if (val[fail[u]]) val[u] = 1;
for (int i = 0; i < charset; i++) {
int &v = ch[u][i];
if (v) {
*e++ = v;
fail[v] = ch[fail[u]][i];
} else {
v = ch[fail[u]][i];
}
}
}
}
/*
dp[i][j]表示长度为i。后缀为j的状态 最多就仅仅有10*10个后缀
所以可以通过dp[n][j] = a0 * dp[n-1][0] + ... + ak * dp[n - 1][k]得到状态转移的矩阵
*/
void work() {
for (int i = 0; i < sz; i++) {
for (int j = 0; j < charset; j++) {
//对于i状态,通过加入ACTG可以得到新的状态(且之前已经构造过AC自己主动机,ch[i][j]便表示新状态)
if (!val[i] && !val[ch[i][j]]) { //两个状态都必须是可行的,转化才有意义
A.a[i][ch[i][j]]++;
}
}
}
}
} AC; Matrix Matrix_pow(Matrix A, ll k, ll mod) {
res.clear();
res.n = res.m = AC.sz;
for (int i = 0; i < AC.sz; i++) res.a[i][i] = 1;
while(k) {
if (k & 1) res = res * A;
A = A * A;
k >>= 1;
}
return res;
}
int main () {
int m, n;
A.clear();
AC.init();
AC.reset();
char str[15];
scanf("%d%d", &m, &n);
for (int i = 0; i < m; i++) {
scanf("%s", str);
AC.Insert(str, 1);
}
A.n = A.m = AC.sz;
AC.Construct();
//之前的都是AC自己主动机构造部分
AC.work(); //得到状态转移的矩阵
res = Matrix_pow(A, n, mod);
int ans = 0;
rep(i, AC.sz) ans += res.a[0][i];
printf("%d\n", ans % mod);
return 0;
}

POJ 2778 DNA Sequence (AC自己主动机 + dp)的更多相关文章

  1. poj 1699 Best Sequence(AC自己主动机+如压力DP)

    id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence 题目大意:给定N个D ...

  2. poj 2778 DNA Sequence AC自动机

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  3. poj 2778 DNA Sequence AC自动机DP 矩阵优化

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  4. POJ 2778 DNA Sequence ( AC自动机、Trie图、矩阵快速幂、DP )

    题意 : 给出一些病毒串,问你由ATGC构成的长度为 n 且不包含这些病毒串的个数有多少个 分析 : 这题搞了我真特么久啊,首先你需要知道的前置技能包括 AC自动机.构建Trie图.矩阵快速幂,其中矩 ...

  5. Hdu 2457 DNA repair (ac自己主动机+dp)

    题目大意: 改动文本串的上的字符,使之不出现上面出现的串.问最少改动多少个. 思路分析: dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...

  6. poj 2778 DNA Sequence ac自动机+矩阵快速幂

    链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...

  7. POJ 2778 DNA Sequence (AC自动机,矩阵乘法)

    题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. #include<iostream> #includ ...

  8. POJ 2778 DNA Sequence (AC自动机+DP+矩阵)

    题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...

  9. 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: ...

随机推荐

  1. 关于SQL Server 数据库的备份

    备份 第一 :选择数据库右键任务,然后直接选择分离,再选择删除和更新上打勾,之后到sqlsever安装目录下查看,会生成xx.mdf和xx.ldf两个文件(既有表结构又有数据). 第二:可以选择备份, ...

  2. WPF程序中处理Windows消息

    首先通过WindowInteropHelper类,我们可以获取WPF Window的Handle. WindowInteropHelper helper = new WindowInteropHelp ...

  3. unity3d游戏开发 —— 倒计时

    using UnityEngine;using System.Collections; public class CoolTime : MonoBehaviour { // Use this for ...

  4. bzoj3774

    这算是最小割中比较难的吧 看到选取显然最小割 看到上下左右四个点我感觉肯定和染色相关 注意每个点的收益获得条件是[或],因此我们考虑拆点i', i,分别表示通过四周控制和控制本身的代价 连边s--&g ...

  5. ehcache 分布式集群同步数据实例

    本文使用rmi方式,借鉴百度能搜到的文章,但是均不能做到数据同步,做了些改动完全没问题,更详细说明介绍百度即可.直奔主题,可运行的demo实例! 创建一个maven项目,配置pom pom.xml & ...

  6. 我个人有关 Azure 网络 SLA、带宽、延迟、性能、SLB、DNS、DMZ、VNET、IPv6 等的 Azure 常见问题解答

    Igor Pagliai(微软)   2014 年 9月 28日上午 5:57  年 11 月 3 年欧洲 TechEd 大会新宣布的内容). 重要提示:这篇文章中我提供的信息具有时间敏感性,因为这些 ...

  7. 设计模式:Observer(观察者)—— Guava EventBus

    本文分为三个部分:   Observer(观察者) Guava EventBus详解 Guava EventBus使用示例   1. Observer(观察者)   1.1 背景   我们设计系统时, ...

  8. MySQL查询大小写是否敏感问题分析

    mysql数据库在做查询时候,有时候是英文字母大小写敏感的,有时候又不是的,主要是由mysql的字符校验规则的设置决定的,通常默认是不支持的大小写字母敏感的.  1. 什么是字符集和校验规则? 字符集 ...

  9. C# DataGridView绑定数据源的几种常见方式

    开始以前,先认识一下WinForm控件数据绑定的两种形式,简单数据绑定和复杂数据绑定. 1. 简单的数据绑定 例1 using (SqlConnection conn = new SqlConnect ...

  10. OWASP Top 10 – 2013, 最新十大安全隐患(ASP.NET解决方法)

    OWASP(开放Web软体安全项目- Open Web Application Security Project)是一个开放社群.非营利性组织,目前全球有130个分会近万名会员,其主要目标是研议协助解 ...