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

解题思路:

有这样的性质:

1.只能形成1个大回文串。

2.只能生成偶回文串。 很有动归的思想嘛。 回文树上一个节点代表一个回文串,dp[i]表示在i节点的回文串最小生成代价:

其中mid为长度小于len[i]/2的最长后缀回文串所在节点,可以倍增跳也可以从fa的mid开始跳。

那么答案就是:

就愉快地结束了。

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
struct pant{
int tranc[];
int len;
int pre;
int dp;
int mid;
}h[],stpant;
int a[];
char tmp[];
int siz;
int fin;
int len;
int trans(char t)
{
if(t=='A')
return ;
if(t=='G')
return ;
if(t=='C')
return ;
return ;
}
void Res(void)
{
memset(a,0x3f,sizeof(a));
a[]=-;
h[]=h[]=stpant;
h[].pre=h[].pre=;
h[].len=-;
h[].dp=;
siz=;
fin=;
return ;
}
bool mis(int i,int lsp)
{
return a[i]!=a[i-h[lsp].len-];
}
void Insert(int i)
{
int nwp,lsp,mac;
lsp=fin;
int c=a[i];
while(mis(i,lsp))
lsp=h[lsp].pre;
if(!h[lsp].tranc[c])
{
nwp=++siz;
mac=h[lsp].pre;
h[nwp]=stpant;
h[nwp].len=h[nwp].dp=h[lsp].len+;
while(mis(i,mac))
mac=h[mac].pre;
h[nwp].pre=h[mac].tranc[c];
h[lsp].tranc[c]=nwp; if(h[nwp].len<=)
h[nwp].mid=h[nwp].pre;
else{
mac=h[lsp].mid;
while(mis(i,mac)||h[mac].len*+>h[nwp].len)
mac=h[mac].pre;
h[nwp].mid=h[mac].tranc[c];
}
if(h[nwp].len%==)
{
h[nwp].dp=std::min(h[lsp].dp+,h[nwp].len/-h[h[nwp].mid].len+h[h[nwp].mid].dp+);
}
}
fin=h[lsp].tranc[c];
return ;
}
int main()
{
int T=;
scanf("%d",&T);
while(T--)
{
Res();
scanf("%s",tmp+);
int ans;
len=strlen(tmp+);
ans=len;
for(int i=;i<=len;i++)
a[i]=trans(tmp[i]);
for(int i=;i<=len;i++)
Insert(i);
for(int i=;i<=siz;i++)
{
if(h[i].len&^)
{
ans=std::min(ans,len-h[i].len+h[i].dp); }//printf("%d\n",h[i].dp);
}
//return 0;
printf("%d\n",ans);
}
return ;
}

BZOJ4044: [Cerc2014] Virus synthesis(回文树+DP)的更多相关文章

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

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

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

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

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

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

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

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

  5. [BZOJ4044]Virus synthesis 回文自动机的DP

    4044: [Cerc2014] Virus synthesis Time Limit: 20 Sec  Memory Limit: 128 MB Description Viruses are us ...

  6. Palindrome Partition CodeForces - 932G 回文树+DP+(回文后缀的等差性质)

    题意: 给出一个长度为偶数的字符串S,要求把S分成k部分,其中k为任意偶数,设为a[1..k],且满足对于任意的i,有a[i]=a[k-i+1].问划分的方案数. n<=1000000 题解: ...

  7. bzoj4044 [Cerc2014] Virus synthesis

    回文自动机上dp f[x]表示形成x代表的回文串所需的最小步数, 若len[x]为奇数,f[x]=len[x],因为即使有更优的,也是直接添加,没有复制操作,那样就不用从x转移了. 若len[x]为偶 ...

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

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

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

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

随机推荐

  1. 51Nod 1405 树的距离之和(dp)

    1405 树的距离之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 给定一棵无根树,如果它有n个节点,节点编号从1到n, 求随意两点之间的距离( ...

  2. 轻松python专题--文本

    基础篇:(取材于零基础学python) 7.1 python中的字符串简单介绍与经常使用函数 7.2 字符串常量 7.3 字符串的一般使用 7.4 改动字符串实例 7.5 文本解析 7.6 字符串格式 ...

  3. rgba

    正反两面展示效果 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head& ...

  4. LINQ查询基础

    一.什么是LINQ LINQ是Language Integrate Query的缩写,意为语言集成查询,是微软在.Net Framework 4.5版中推出的主要特性之一. 它为开发人员提供了统一的数 ...

  5. 是时候抛弃web.xml了?

    你是否再为配置文件web.xml容易出错而烦恼?是否为web.xml文件存放位置而不知所措?是否为web.xml为什么要这样配?怎么才能更好的配置web.xml而烦恼?那么一种新的方式出现了: spr ...

  6. asp.net 关于cookie的操作

    一.无子键或单级cookie 读写(1).写入: 第一种 HttpCookie cookie=new HttpCookie("User"); cookie.Value=" ...

  7. Vue常见面试题汇总

    Vue框架常见面试题   1.active-class是哪个组件的属性?嵌套路由怎么定义? 答:vue-router模块的router-link组件. 2.怎么定义vue-router的动态路由?怎么 ...

  8. 紫书 习题 10-18 UVa 10837 (欧拉函数变形)

    这道题很巧妙,要把式子变一下 phi(n) = n * (1 - 1 / p1) * (1 - 1 / p2)--(1 - 1 / pr) = n * ((p1-1) / p1) * ((p1-2) ...

  9. PopupWindow的一些属性

     void setOutsideTouchable(boolean touchable)            Controls whether the pop-up will be informed ...

  10. jquery11源码 animate() : 运动的方法

    { var fxNow, timerId, rfxtypes = /^(?:toggle|show|hide)$/, rfxnum = new RegExp( "^(?:([+-])=|)( ...