洛谷P4762 [CERC2014]Virus synthesis(回文自动机+dp)
回文自动机的好题啊
先建一个回文自动机,然后记$dp[i]$表示转移到$i$节点代表的回文串的最少的需要次数
首先肯定2操作越多越好,经过2操作之后的串必定是一个回文串,所以最后的答案肯定是由一个回文串+不断暴力添加得来,那么答案就是$min(ans,dp[i]+n-len[i])$
然后对于一个串$i$,如果它在前面和后面加上一个字母可以形成回文串$j$,则$dp[j]=dp[i]+1$
为啥嘞?我们可以假设在形成$i$的之前一步把这个字母加上去,执行2操作后就可以变成$j$了
然后我们可以fail指针找到最长的回文串$x$满足$len[x]<=len[i]/2$,那么$dp[i]=min(dp[i],dp[x]+1+len[i]/2-len[x])$(先暴力填好一半,剩下的用2操作)
然后可以用队列记录状态,保证转移至有序的
至于怎么找$x$,我们可以直接在建自动机的时候顺便求出来,就是多跳几次。这个看代码好了
//minamoto
#include<cstring>
#include<cstdio>
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
const int N=2e5+,M=;
char s[N];int dp[N],len[N],fail[N],ch[N][M];
int trans[N],last,p,q,str[N],tot,ans,n,qu[N];
int val[];
inline int newnode(int x){
len[++tot]=x;memset(ch[tot],,sizeof(ch[tot])*);return tot;
}
inline int getfail(int x,int n){
while(s[n-len[x]-]!=s[n]) x=fail[x];return x;
}
inline void init(){
val['A']=,val['T']=,val['C']=,val['G']=;
s[]=-,fail[]=,last=;
len[]=,len[]=-,tot=;
memset(ch[],,sizeof(int)*),memset(ch[],,sizeof(int)*);
}
void ins(int c,int i){
p=getfail(last,i);
if(!ch[p][c]){
q=newnode(len[p]+);
fail[q]=ch[getfail(fail[p],i)][c];
ch[p][c]=q;
if(len[q]<=) trans[q]=fail[q];
else{
int tmp=trans[p];
while(s[i--len[tmp]]!=s[i]||(len[tmp]+)*>len[q]) tmp=fail[tmp];
trans[q]=ch[tmp][c];
}
}
last=ch[p][c];
// printf("%d\n",last);
}
int main(){
// freopen("testdata.in","r",stdin);
int T;scanf("%d",&T);
while(T--){
scanf("%s",s+);
init(),ans=n=strlen(s+);
for(int i=;i<=n;++i) ins(val[s[i]],i);
for(int i=;i<=tot;++i) dp[i]=len[i];
int h=,t=;qu[++t]=,dp[]=;
while(h<=t){
int u=qu[h++];
for(int i=;i<;++i){
int x=ch[u][i];
if(!x) continue;
dp[x]=dp[u]+;
int y=trans[x];
cmin(dp[x],dp[y]++len[x]/-len[y]);
cmin(ans,dp[x]+n-len[x]);
qu[++t]=x;
}
}
printf("%d\n",ans);
}
return ;
}
洛谷P4762 [CERC2014]Virus synthesis(回文自动机+dp)的更多相关文章
- bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp)
		
bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp) bzoj Luogu 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符 ...
 - BZOJ 4044 Luogu P4762 [CERC2014]Virus Synthesis (回文自动机、DP)
		
好难啊..根本不会做..基本上是抄Claris... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4044 (luogu) ...
 - luogu P4762 [CERC2014]Virus synthesis (回文自动机)
		
大意: 初始有一个空串, 操作(1)在开头或末尾添加一个字符. 操作(2)在开头或末尾添加该串的逆串. 求得到串$S$所需最少操作数. 显然最后一定是由某个偶回文通过添加字符得到的, 那么只需要求出所 ...
 - BZOJ 4044 Virus synthesis (回文自动机+dp)
		
题目大意: 你可以在一个串的开头或者末尾加入一个字符,或者把当前整个串$reverse$,然后接在前面或者后面,求达到目标串需要的最少操作次数 对目标串建出$PAM$ 定义$dp[x]$表示当前在回文 ...
 - [BZOJ4044]Virus synthesis 回文自动机的DP
		
4044: [Cerc2014] Virus synthesis Time Limit: 20 Sec Memory Limit: 128 MB Description Viruses are us ...
 - bzoj 4044: Virus synthesis 回文自动机
		
题目大意: 你要用ATGC四个字母用两种操作拼出给定的串: 将其中一个字符放在已有串开头或者结尾 将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空.求最少操作次数. le ...
 - bzoj 4044 Virus synthesis - 回文自动机 - 动态规划
		
题目传送门 需要高级权限的传送门 题目大意 要求用两种操作拼出一个长度为$n$的只包含'A','T','G','C'的字符串 在当前字符串头或字符串结尾添加一个字符 将当前字符串复制,将复制的串翻转, ...
 - bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)
		
bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp) bzoj Luogu 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一 ...
 - [CERC2014]Virus synthesis【回文自动机+DP】
		
[CERC2014]Virus synthesis 初始有一个空串,利用下面的操作构造给定串 SS . 1.串开头或末尾加一个字符 2.串开头或末尾加一个该串的逆串 求最小化操作数, \(|S| \l ...
 
随机推荐
- Mybatis_笔记_01_逆向工程
			
通过Mybatis逆向工程,可以从数据库中的表自动生成pojo.mapper映射文件和mapper接口 此处暂存怎么使用逆向工程,原理以后再探讨 工程结构 要修改的地方:generatorConfig ...
 - BEC  listen and translation exercise 43
			
Reach for the stars so if you fall you land on a cloud.飞向星空吧,就算坠落,接住你的也是云彩. Anyway, exam failure can ...
 - 汇编题目:在屏幕中间显示a-z的所有字母,按ESC键改变字符颜色
			
在屏幕中显示a-z字母,按ESC键改变字符颜色. ;程序功能:在屏幕中间同一点显示a-z的所有字符 ; 1.使用cpu循环空运行实现延迟 ; 2.按ESC键改变正在循环显示的字符的颜色 ; 3.程序完 ...
 - tcpdump示例
			
今天有需求要用tcpdump,给一个我使用的例子: sudo /usr/sbin/tcpdump dst 10.20.137.24 and tcp port 8080 -A -s0 -w nous ...
 - Python图片识别——人工智能篇
			
一.安装pytesseract和PIL PIL全称:Python Imaging Library,python图像处理库,这个库支持多种文件格式,并提供了强大的图像处理和图形处理能力. 由于PIL仅 ...
 - linux命令-gzip压缩
			
把很大的目录/文件压缩成更小的文件,传输节省带宽,从服务端到客户端下载过程节省时间,减少带宽,节省使用率.使用cpu的资源. 压缩命令gzip [root@wangshaojun ~]# ls111. ...
 - Java 决策制定
			
有两种类型的决策在Java中的语句,它们分别是: if 语句 switch 语句 if 语句: if语句由一个布尔表达式后跟一个或多个语句. 语法: if语句的语法是: if(Boolean_expr ...
 - Delegate Action<T in> Func<T in,out Tresult> Predicate<T>
			
action<T> 和 func<T> 都是delegate的简写形式,其中T为可以接受的参数类型 action<T> 指那些只有输入参数,没有返回值 Deleg ...
 - tomcat jsp 数字串传值异常问题
			
1.在下面的jsp内嵌java代码去除num之前,有某Controller已经有了操作: request.getSession().setAttribute("num", ...
 - badblocks 检查磁盘损坏的区块
			
Linux badblocks命令用于检查磁盘装置中损坏的区块. 语法: badblocks [-svw][-b <区块大小>][-o <输出文件>][磁盘装置][磁盘区块数] ...