基因合成
来源:互联网 发布:c语言break实例 编辑:程序博客网 时间:2024/06/11 01:56
题目描述
回文自动机
首先,我们可以认为,每个最终串都是进行若干操作后进行了一次第二个操作后,再在两端插入而得到的。
先对最终串插入回文自动机上,然后做动态规划。
我们设f[i]表示i这个结点所代表的回文串最后一次操作是第二个操作需要多少个操作得到。
注意偶数树的根节点f值为1。
fa[i]表示其在回文树上的父亲,pre[i]表示其最长长度不超过其的长度的一半的回文后缀。pre怎么求呢?显然沿着fail一直跳跳到第一个长度符合要求的即可。
然而这样找pre的复杂度是玄学的(是的能过但是我们思索如果是一堆a呢?),所以其实正解估计是倍增。
如果结点i是奇回文串,f[i]=len[i]。
否则f[i]=min(f[fa[i]]+1,f[pre[i]]+len[i]/2-len[pre[i]]+1)
答案怎么求?
枚举回文树上每个结点,然后ans=min(ans,n-len[i]+f[i])
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=100000+10;int f[maxn],g[maxn][5],fail[maxn],pre[maxn],fa[maxn],len[maxn];int i,j,k,l,t,n,m,tot,ca,ans,last;char ch;char s[maxn];void insert(int c){ int x=last; while (s[i-len[x]-1]!=s[i]) x=fail[x]; if (!g[x][c]){ fa[++tot]=x; len[tot]=len[x]+2; int y=fail[x]; while (s[i-len[y]-1]!=s[i]) y=fail[y]; fail[tot]=g[y][c]; y=g[y][c]; while (len[y]>len[tot]/2) y=fail[y]; pre[tot]=y; if (len[tot]%2==0) f[tot]=min(f[fa[tot]]+1,f[pre[tot]]+len[tot]/2-len[pre[tot]]+1); else f[tot]=len[tot]; g[x][c]=tot; } last=g[x][c];}int main(){ //freopen("dna4.in","r",stdin); scanf("%d",&ca); while (ca--){ scanf("%s",s+1); n=strlen(s+1); ans=n; fail[0]=fail[1]=tot=1; len[1]=-1; f[1]=2; f[0]=1; fo(i,0,n) fo(j,0,3) g[i][j]=0; last=0; fo(i,1,n){ if (s[i]=='A') t=0; else if (s[i]=='T') t=1; else if (s[i]=='C') t=2;else t=3; insert(t); } fo(i,2,tot) ans=min(ans,n-len[i]+f[i]); printf("%d\n",ans); }}
0 0
- 基因合成
- 合成基因的方式
- JZOJ4387. 【GDOI2016模拟3.15】基因合成
- 基因
- 合成
- 合成
- 合成
- 基因预测
- 企业家基因
- 山寨基因
- 职业基因
- 基因检测
- 基因牛
- 基因 (BFS)
- 印记基因
- 基因牛
- 基因牛
- 基因牛
- 【DP】HDU 1087
- 删除排序数组中的重复数字
- [UWP]MD5加密
- Android 实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音
- 【OpenCV】CvMat的用法详解及实例
- 基因合成
- 用MFC制作程序启动logo
- 我对 Linux 又爱又痛的五个原因(转)
- 【Spring实战】—— 10 AOP针对参数的通知
- Jquery弹窗跳转
- Android四大基本组件之 BroadcastReceiver介绍
- 中断与异常(一)
- Android四大基本组件之 Service
- Android四大基本组件之 Activity