POJ 2778 DNA Sequence AC自动机+DP+快速幂
来源:互联网 发布:淘宝关键词的大中小词 编辑:程序博客网 时间:2024/05/31 13:16
http://poj.org/problem?id=2778
题意:
给n个病毒基因 长度不超过10
要你构造一个长度为n的字符串,不能包含任何病毒基因
求方案数
用病毒基因构建ac自动机。
考虑节点作为一个状态,初始状态是在根节点。
建立二维矩阵,
(dp[i][j]表示从状态节点i走一部能到达状态节点j的方案数
(根据ac自动机建立一个sz*sz大小的矩阵
(判断能否到达就看trie[i][j]这个节点是否为结束标记
那么初始矩阵A的dp[i][j]就是i节点 经过一步 到达j节点的方案数
显然A^2 中的dp[i][j]表示 i 经过2步到达 j的 方案数
因此求个A^k
然后我们看根节点0 能到达其他节点的方案数 之和就是答案
即表示 根节点出发 走了n步,最后以 其他节点为结尾的方案数 之和。
#include<bits/stdc++.h>using namespace std;const int N=10005;const int maxlen=1000132;const int maxn=10005*50;const int all_size=26;int trie[maxn][all_size];int fail[maxn];int tag[maxn];int sz;queue<int >Q;struct Aho{ int root=0; int newnode()//静态创建新节点 { memset(trie[sz],-1,sizeof trie[sz]); tag[sz]=0; sz++; return sz-1; } void init()//初始化 { sz=0; newnode(); } void insert(char s[]) //插入字符串构建ac自动机,构建trie树 { int len=strlen(s),p=0;; for (int i=0; i<len; i++) { int id=s[i]-'a'; if (trie[p][id]==-1) trie[p][id]=newnode(); p=trie[p][id]; } tag[p]++; //结束标记 } void getfail() //构建自动机fail指针 { while(!Q.empty()) Q.pop(); fail[root]=root; //root指向root for (int i=0; i<all_size; i++) { if (trie[root][i]==-1)//第一个字符不存在,指向root trie[root][i]=root; else //第一个字符的fail指针指向root { fail[trie[root][i]]=root; Q.push(trie[root][i]); //并放入队列,待bfs扩展 } } while(!Q.empty()) { int u=Q.front(); //取扩展节点 Q.pop(); if(tag[fail[u]]) tag[u]=1; //***表示基因包含的情况,也要tag标记 for (int i=0; i<all_size; i++)//遍历所有子节点 { if (trie[u][i]==-1)//如果不存在,则子节点直接指向fail[u]节点的对应子节点 trie[u][i]=trie[fail[u]][i]; else //如果存在,则该节点的fail指针指向fail[u]节点对应的子节点 { faitrie[u][i]]=trie[fail[u]][i]; Q.push(trie[u][i]); //继续扩展 } } } }} aho;char ss[55];char s[maxlen];int main(){ int t; scanf("%d",&t); while(t--) { aho.init(); int n; cin>>n; for (int i=0; i<n; i++) { scanf("%s",ss); aho.insert(ss); } aho.getfail(); scanf("%s",s); int len=strlen(s); int p=aho.root; int ans=0; for (int i=0; i<len; i++) { int idx=s[i]-'a'; p=trie[p][idx]; int tmp=p; //取出当前字符在自动机上对应的节点 while(tmp!=aho.root)//如果有fail节点则一直往上跳,直到跳回root表示没有了fail后 { ans+=tag[tmp];//累计答案 tag[tmp]=0;//清空tag标记 tmp=fail[tmp];//跳到fail后继节点 } } printf("%d\n",ans); } return 0;}
0 0
- poj 2778 DNA Sequence 【ac自动机 + dp + 矩阵快速幂】
- [AC自动机+dp+矩阵快速幂] poj 2778 DNA Sequence
- POJ 2778 DNA Sequence AC自动机+DP+快速幂
- POJ 2778 DNA Sequence (AC自动机 + dp)
- POJ 2778 DNA Sequence(AC自动机+矩阵幂DP)
- POJ 2778 DNA Sequence(AC自动机+矩阵幂DP)
- POJ 2778:DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence【AC自动机+矩阵快速幂】
- poj 2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 - DNA Sequence (AC自动机 矩阵快速幂)
- POJ 2778DNA Sequence AC自动机 + 矩阵快速幂
- 【AC自动机+矩阵快速幂】 POJ 2778 DNA Sequence
- poj 2778 DNA Sequence AC自动机+矩阵快速幂
- poj 2778 DNA Sequence(AC自动机+矩阵快速幂)
- POJ 2778 DNA Sequence AC自动机+矩阵快速幂
- POJ 2778 DNA Sequence [AC自动机 + 矩阵快速幂]
- poj 2778 AC自动机+快速幂(DNA Sequence)
- POJ 2778 DNA Sequence (AC自动机 + 矩阵快速幂)
- Balanced Binary Tree(Java)
- 注册MiniFilter简单的隐藏自身
- tjut 5894
- c语言词法分析器的简单实现
- 对gcc一些优化项目的具体说明
- POJ 2778 DNA Sequence AC自动机+DP+快速幂
- U8+12.5相关服务和端口
- [cogs2525][树状数组]卡片游戏
- 【jzoj3104】【疫情控制】
- 单源最短路径 -- Dijkstra算法
- Intent传值 与 传递类对象
- 树莓派远程桌面,error problem connecting
- hdu1712 ACboy needs your help(分组背包)
- Stream数据流