4044: [Cerc2014] Virus synthesis

Time Limit: 20 Sec  Memory Limit: 128 MB

Description

Viruses are usually bad for your health. How about fighting them with... other viruses? In 
this problem, you need to find out how to synthesize such good viruses. 
We have prepared for you a set of strings of the letters A, G, T and C. They correspond to the 
DNA nucleotide sequences of viruses that we want to svnthesize, using the following operations: 
* Adding a nucleotide either to the beginning or the end of the existing sequence 
* Replicating the sequence, reversing the copied piece, and gluing it either to the beginmng or 
to the end of the original (so that e.g., AGTC can become AGTCCTGA or CTGAAGTC). 
We're concerned about efficiency, since we have very many such sequences, some of them verv 
long. Find a wav to svnthesize them in a mmimum number of operations. 
你要用ATGC四个字母用两种操作拼出给定的串: 
1.将其中一个字符放在已有串开头或者结尾 
2.将已有串复制,然后reverse,再接在已有串的头部或者尾部 
一开始已有串为空。求最少操作次数。 
len<=100000 

Input

The first line of input contains the number of test cases T. The descriptions of the test cases 
follow: 
Each test case consists of a single line containing a non-empty string. The string uses only 
the capital letters A, C, G and T and is not longer than 100 000 characters. 

Output

For each test case, output a single line containing the minimum total number of operations 
necessary to construct the given sequence.

Sample Input

4
AAAA
AGCTTGCA
AAGGGGAAGGGGAA
AAACAGTCCTGACAAAAAAAAAAAAC

Sample Output

3
8
6
18
 
题解:
这道题是一道回文自动机的DP好题啊。。。很难想,解释起来似乎也很混乱,
有不明白欢迎询问,因为这样写题解也不能完全解释明白233
 我们考虑,假设答案为ans,那初始化ans=串长.
如果ans能够减小,那一定是某一个回文串通过复制来做出的贡献.
注意,只能是一个,因为一旦复制就要复制全串,
最终的目标串一定是添加字符(可以是0个,即不添加)形成的,而不可能有两段复制.
由于这是一个回文有关题目......manacher看起来还不能搞
所以我们只好先把回文自动机建出来,对于回文自动机上每个节点i设f[i]表示生成节点i代表的串所需要的最少操作次数
那么这个串的生成可以是在对称轴外侧填字符+复制,也可以是在对称轴内侧填字符+复制
如果是在外侧:
假设串i可以在串j复制之前在外侧添加一个字符+复制得到,
那么我们可以想到,f[i]=min(f[j]+1)
或者,f[i]可以通过某个回文后缀对称轴内侧填字符+复制得到,
那么这个回文后缀的长度一定小于len[i]/2
回文后缀我们可以通过暴力跳fail指针来寻找
转移方程为f[i]=min(len[i]/2+f[j]-len[j]+1)
但是对于本题的数据范围这样会T掉……
那么我们考虑,对于i的某个可行复制串回文字串j,以及fail[j]
f[j]-len[j]的值显然要大于f[fail[j]]-len[fail[j]],那么我们只需要考虑第一个合法决策点,比它长的不会更优秀
但是这样还是会T……
所以我们考虑对于某个节点i,我们可以记录它的第一个最优决策点。
那么它的最优决策点可以从它的fail的最优决策点开始选择
(由于i和fail[i]的查找路径是一样的,len[fail]比len[i]长度更短,那么对于fail合法对于i也会合法)
所以在寻找i的决策点时,我们从fail[i]的最优决策点开始查找即可。
这样构建回文自动机的时候处理决策点,再遍历一遍求出每个串的f值,最后答案就是ans=min(n-len[i]+f[i])
代码实现:
 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=,inf=0x7fffffff;
char s[N];
struct Pam_Tree
{
int n,m,last,p,strategy[N];
int ch[N][],len[N],fail[N],f[N];
int q[N],hd,tl;
inline int id(char x)
{
switch(x)
{
case 'A':return ;
case 'C':return ;
case 'G':return ;
case 'T':return ;
}
return ;
}
inline int newnode(int l)
{
len[p]=l;memset(ch[p],,sizeof(ch[p]));
fail[p]=f[p]=strategy[p]=;
return p++;
}
inline int getfail(int x)
{
while(s[n-len[x]-]!=s[n])x=fail[x];
return x;
}
inline void work()
{
register int i,x,u;
hd=,tl=,q[++tl]=,f[]=;
int ans=m;
for(i=;i<p;++i)if(len[i]&)f[i]=i;
while(hd<=tl)
for(x=q[hd++],i=;i<;++i)
if((u=ch[x][i]))
q[++tl]=u,
f[u]=min(f[x]+,len[u]/+f[strategy[u]]-len[strategy[u]]+),
ans=min(ans,f[u]+m-len[u]);
printf("%d\n",ans);
}
inline void insert()
{
register int i,now,cur,d,x;
for(n=;n<=m;++n)
{
d=id(s[n]),cur=getfail(last);
if(!ch[cur][d])
{
now=newnode(len[cur]+),
fail[now]=ch[getfail(fail[cur])][d],
ch[cur][d]=now;
if(len[now]<=)strategy[now]=fail[now];
else
{
x=strategy[cur];
while(s[n-len[x]-]!=s[n]||(len[x]+)*>len[now])x=fail[x];
strategy[now]=ch[x][d];
}
}
last=ch[cur][d];
}
work();
}
inline void intn()
{
scanf("%s",s+),p=,newnode(),newnode(-);
s[]=,m=strlen(s+),last=,fail[]=,insert();
}
}PT;
int main()
{
int t;scanf("%d",&t);
while(t--)PT.intn();
}

[BZOJ4044]Virus synthesis 回文自动机的DP的更多相关文章

  1. BZOJ 4044 Luogu P4762 [CERC2014]Virus Synthesis (回文自动机、DP)

    好难啊..根本不会做..基本上是抄Claris... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4044 (luogu) ...

  2. bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp)

    bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp) bzoj Luogu 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符 ...

  3. bzoj 4044: Virus synthesis 回文自动机

    题目大意: 你要用ATGC四个字母用两种操作拼出给定的串: 将其中一个字符放在已有串开头或者结尾 将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空.求最少操作次数. le ...

  4. BZOJ 4044 Virus synthesis (回文自动机+dp)

    题目大意: 你可以在一个串的开头或者末尾加入一个字符,或者把当前整个串$reverse$,然后接在前面或者后面,求达到目标串需要的最少操作次数 对目标串建出$PAM$ 定义$dp[x]$表示当前在回文 ...

  5. bzoj 4044 Virus synthesis - 回文自动机 - 动态规划

    题目传送门 需要高级权限的传送门 题目大意 要求用两种操作拼出一个长度为$n$的只包含'A','T','G','C'的字符串 在当前字符串头或字符串结尾添加一个字符 将当前字符串复制,将复制的串翻转, ...

  6. luogu P4762 [CERC2014]Virus synthesis (回文自动机)

    大意: 初始有一个空串, 操作(1)在开头或末尾添加一个字符. 操作(2)在开头或末尾添加该串的逆串. 求得到串$S$所需最少操作数. 显然最后一定是由某个偶回文通过添加字符得到的, 那么只需要求出所 ...

  7. [加强版] Codeforces 835D Palindromic characteristics (回文自动机、DP)

    题目链接: https://codeforces.com/contest/835/problem/D 题意: 一个回文串是\(1\)-回文的,如果一个回文串的左半部分和右半部分一样且都是\(k\)-回 ...

  8. [CERC2014]Virus synthesis【回文自动机+DP】

    [CERC2014]Virus synthesis 初始有一个空串,利用下面的操作构造给定串 SS . 1.串开头或末尾加一个字符 2.串开头或末尾加一个该串的逆串 求最小化操作数, \(|S| \l ...

  9. 洛谷P4762 [CERC2014]Virus synthesis(回文自动机+dp)

    传送门 回文自动机的好题啊 先建一个回文自动机,然后记$dp[i]$表示转移到$i$节点代表的回文串的最少的需要次数 首先肯定2操作越多越好,经过2操作之后的串必定是一个回文串,所以最后的答案肯定是由 ...

随机推荐

  1. 大学生Linux常用命令(一)

    大学生Linux常用命令(一) 1.1 命令格式 命令格式一般为---命令名 [选项] [参数1] [参数2]- 例如:cp -I file1 cp为命令名,-l为选项,file1为参数. 其中,命令 ...

  2. jar包冲突常用的解决方法

    jar包冲突常见的异常为找不到类(java.lang.ClassNotFoundException).找不到具体方法(java.lang.NoSuchMethodError).字段错误( java.l ...

  3. 微信小程序video视频组件

    支持mp4和m3u8的视频格式,其中mp4的需要是h264的视频编码 .1.如果您使用video组件是mp4的但不能播放,大部分是由于编码的问题,当然排除文件不存在等这些客观的因素条件.2.如果使用m ...

  4. Influxdb配置文件详解---influxdb.conf

    官方介绍:https://docs.influxdata.com/influxdb/v1.2/administration/config/ 全局配置 1 2 reporting-disabled =  ...

  5. 我对BP网络的简单的理解

    最近在学习tf的神经网络算法,十多年没有学习过数学了,本来高中数学的基础,已经彻底还给数学老师了.所以我把各种函数.公式和推导当做黑盒子来用,理解他们能做到什么效果,至于他们是如何做到的,暂时不去深究 ...

  6. 查看linux端口对应的进程id

    例如:查看占用4040端口的进程 ss -lptn 'sport = :4040'

  7. umount命令详解

    基础命令学习目录首页                                    umount 用来卸载设备 -a:卸除/etc/mtab中记录的所有文件系统: -h:显示帮助: -n:卸除 ...

  8. nodejs的Cannot find module 'body-parser'

    http://blog.csdn.net/u014345860/article/details/77769253

  9. 实验三 敏捷开发与XP实践 实验报告 20135232王玥

    一.实验内容 1. XP基础 2. XP核心实践 3. 相关工具 二.实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程 2. ...

  10. bata2

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...