HDU 3962 / HIT 3045 Microgene--ac自动机 动态规划
来源:互联网 发布:tensorflow 二次开发 编辑:程序博客网 时间:2024/04/27 21:53
http://acm.hdu.edu.cn/showproblem.php?pid=3962
http://acm.hit.edu.cn/judge/show.php?Proid=3045
这场赛真悲剧 前4小时没交题 一直在想那个找环的题 结果最后试了下居然暴力就能过>.
A了那个找环题 同学就上去把积分过了 然后我看B题 看完后AC自动机能搞
状态转移方程也很明显
dp[l][sta][0]=∑dp[l-1][psta][0]
dp[l][sta][1]=∑dp[l-1][psta][1]
(sta为合法串)
dp[l][sta][0]=0;
dp[l][sta][1]=∑dp[l-1][psta][0]
(sta为非法串)
本来打算先在机器上线性递推验证正确然后再改成矩阵的
尼玛的 滚动数组忘初始化了 找了1个小时都没找出来>...
然后就悲剧了...
由于状态转移是+=的转移 而且用的滚动数组 一个数组会重复利用 下次用之前应该把当前的数组清0
但转移若是取上次的最值之类的就不会出现这种状况 所以这次没意识出来
加上初始化后答案就对了 只是会超时 改成矩阵形式 因为是齐次线性递推的 矩阵行列就是字典树节点数*2 然后m^3logN速度0.02s AC
#include<cstdio>#include<cstring>#include<algorithm> using namespace std;#define KIND 4#define MAXN 66#define INF 0x3fffffff#define MOD 10007#define FF(i,n) for(i=0;i<n;i++)int N;struct IM{ int el[MAXN][MAXN];};IM sgl,bas;IM operator * (IM &x,IM &y){ IM r; int i,j,k; FF(i,N) FF(j,N) r.el[i][j]=0; FF(i,N) FF(k,N) if(x.el[i][k]) FF(j,N) if(y.el[k][j]){ r.el[i][j]+=x.el[i][k] * y.el[k][j];if(r.el[i][j]>=MOD)r.el[i][j]%=MOD;} return r;}IM operator ^ (IM x,int m){ IM r=sgl; for(;m;m>>=1) { if(m&1) r=r*x; x=x*x; } return r;}struct Node{ int fail; bool end; int next[KIND]; void init() { fail=-1; end=0; memset(next,-1,sizeof(next)); }}node[MAXN];int q[MAXN<<1];int head,tail;int sz; void init(){ sz=0; node[0].init();}int Index(char c){ switch(c) { case 'A':return 0; case 'G':return 1; case 'C':return 2; case 'T':return 3; } return 0;}void Insert(char *str){ int p=0; for(int i=0;str[i];i++) { if(node[p].end) break; int index=Index(str[i]); if(node[p].next[index]==-1) { node[p].next[index]=++sz; node[sz].init(); } p=node[p].next[index]; } node[p].end=1;}void Build_AC(){ int temp; int p=0; head=tail=0; q[tail++]=p; while(head<tail) { temp=q[head++]; for(int i=0;i<KIND;i++) { p=node[temp].next[i]; if(p!=-1) { if(!temp) node[p].fail=0; else { node[p].fail=node[node[temp].fail].next[i]; if(node[node[p].fail].end) node[p].end=1; } q[tail++]=p; } else { if(!temp) node[temp].next[i]=0; else node[temp].next[i]=node[node[temp].fail].next[i]; } } }}int power(int a,int n){ int ret; for(ret=1;n;n>>=1) { if(n&1) ret=ret*a%MOD; a=a*a%MOD; } return ret%MOD;} int main(){ int n,l,i,j; int casenum=0; char words[12]; while(~scanf("%d%d",&n,&l)) { init(); for(i=1;i<=n;i++) { scanf("%s",words); Insert(words); } Build_AC();N=(sz+1)<<1;for(i=0;i<N;i++)for(j=0;j<N;j++){sgl.el[i][j]=i==j;bas.el[i][j]=0;}for(i=0;i<=sz;i++){for(j=0;j<KIND;j++){if(!node[node[i].next[j]].end){bas.el[node[i].next[j]*2][i*2]++;bas.el[node[i].next[j]*2+1][i*2+1]++;}else{bas.el[node[i].next[j]*2+1][i*2]++;}}}IM mat=bas^l;int s=0;for(i=0;i<N;i++){s+=mat.el[i][0];if(s>=MOD)s%=MOD;}int total=power(4,l);int ans=(total-s)%MOD+MOD;printf("%d\n",ans%MOD); } return 0;}
- HDU 3962 / HIT 3045 Microgene--ac自动机 动态规划
- Hdu 3962 Microgene (AC自动机+矩阵)
- hdu 3962 Microgene (ac自动机+矩阵优化(好题))
- HDU 2296 Ring AC自动机 + 动态规划
- HDU 2457 DNA repair AC自动机 + 动态规划
- pku1625 AC自动机,动态规划
- hdu 3962 Microgene
- POJ3691 DNA repair AC自动机+动态规划
- 【AC自动机】基于自动机状态设计的动态规划
- 动态规划和字符串匹配(KMP、AC自动机)
- POJ 1625 Censored! AC自动机 + 动态规划 + 高精度
- 【BZOJ2553】【BeiJing2011】禁忌 AC自动机 矩阵乘法 动态规划
- bzoj 3530: [Sdoi2014]数数 AC自动机&动态规划
- bzoj 1030: [JSOI2007]文本生成器 AC自动机+动态规划
- UVA 11468 Substring(AC自动机+树上的动态规划)
- 【Luogu3041】视频游戏的连击(AC自动机,动态规划)
- hdu 3962(AC自动机+矩阵优化dp)
- AC自动机 hdu 2222
- 考研之英语学习笔记序列之语法学习(不定冠词a和an的探索)
- 汽车积碳的原因、症状及预防方法
- D3D 基本函数,枚举等
- ClientHeight
- 世界上最心痛的感觉
- HDU 3962 / HIT 3045 Microgene--ac自动机 动态规划
- Java IO _System 类对IO的支持
- UNIX2DOS/DOS2UNIX for Windows
- JAVA IO总结
- 关于现状的一些深思
- dotNET资源回收的相关知识
- 最长递增子序列长度问题
- 设计模式-观察者模式
- IO与文件读写---Java的IO流架构