洛谷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 ...
随机推荐
- windows下安装配置nginx
下载nginx-1.0.11.zip, 解压到到nginx目录下 D:\nginx\conf 修改conf下的nginx.conf文件, 默认是80端口,若该端口被占则可以修改 listen 8073 ...
- Oracle学习笔记_04_多表查询
一.概念: 1.多表连接有以下几种分法: (1)内连接 vs 外连接 (左.右.满) (2)等值连接 vs 不等值连接 (3)非自连 ...
- Android 中对于图片的内存优化方法
Android 中对于图片的内存优化方法,需要的朋友可以参考一下 1. 对图片本身进行操作 尽量不要使用 setImageBitmap.setImageResource. BitmapFact ...
- sql split函数
--DROP FUNCTION F_SQLSERVER_SPLIT GO CREATE FUNCTION F_SQLSERVER_SPLIT(@Long_str varchar(8000),@spli ...
- Solaris/Linux 命令手册
无意翻到之前收藏的一个文档,共享一下. Solaris/Linux 命令手册 1. 系统 # passwd:修改口令 # exit:退出系统 2. 文件 # cp:复制文件或目录,参数:-a递归目录, ...
- Oracle 12c 多租户配置和修改 CDB 和 PDB 参数
1. 配置CDB 实例参数,影响CDB与所有 PDB为CDB配置例程参数相对于对于非CDB的数据库是变化不太.ALTER SYSTEM命令用于设置初始化参数,与使用ALTER DATABASE命令修改 ...
- 非系统数据文件损坏,rman备份恢复
实验前提:已经做好备份. SQL> col file_name for a50select file_id,file_name from dba_data_files; FILE_ID FILE ...
- 查看,上传crushmap命令
标签(空格分隔): ceph,ceph运维,crushmap 查看crushmap命令 从mon节点获取crushmap: # ceph osd getcrushmap -o crush.map 反编 ...
- java core
1: Java7 以后的 NIO. 2: 泛型要掌握,这里重点强调一点,泛型类之间不存在继承关系,所有的泛型对象在编译后都会去泛型化,都是同一个 class 对象,例如 ArrayList< ...
- js 取get过来的数据
function getQuery(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&am ...