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. C++语言笔记系列之十——静态成员

    1.静态成员 (1)由keywordstatic修饰 静态变量定义语句在编译阶段就运行,运行过程中不再运行. (2)分类:静态数据成员.静态成员函数. (3)静态成员时类的全部对象共享的成员,而不是某 ...

  2. hdoj--5333--Dancing Stars on Me(水题)

    Dancing Stars on Me Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Ot ...

  3. 关于自适应的矩形css布局

    在面试中遇到的问题,做一个自适应的宽高2:1的矩形,这个问题考察了padding的细节,padding-bottom的百分比值,相对的是该盒模型的height,设置矩形之后,里面的内容如果太多会溢出, ...

  4. BZOJ 1146 二分+链剖+线段树+treap

    思路: 恶心的数据结构题-- 首先 我们 链剖 把树 变成序列 再 套一个 区间 第K大就好了-- 复杂度(n*log^4n) //By SiriusRen #include <cstdio&g ...

  5. 原型,构造函数,实例,__proto__

    再说说__proto__,这个孩子性格慢向,所以即使在现代浏览器广为支持得今天也不建议使用,性能特别慢,而且影响所有来自该[[prototype]]的对象.只是拿出来了解了解: 1.它是个啥? 原型对 ...

  6. 51nod 最大子段和问题

    给出一个整数数组a(正负数都有),如何找出一个连续子数组(可以一个都不取,那么结果为0),使得其中的和最大? 用f[i]表示以i为结尾的最大字段和,也就是说i一定要取, 那么f[i] = max(a[ ...

  7. Android布局之RelativeLayout

    RelativeLayout用到的一些重要的属性: 第一类:属性值为true或falseandroid:layout_centerHrizontal 水平居中android:layout_center ...

  8. EularProject 48: 利用数组求和

    Problem 48 The series, 11+22+33+...+1010=10405071317. Find the last ten digits of the series, 11+22+ ...

  9. Java 实现策略(Strategy)模式

    策略模式:行为型模式 将同一行为,不同的处理算法分别封装起来.让它们之间能够互相替换 1. 定义一个超类型接口,及 行为方法 2. 定义不同的实现类,实现该行为的 不同的算法 /** * 策略模式:针 ...

  10. Cloudera Hue是什么?

     Hue是cdh专门的一套web管理器,它包括3个部分hue ui,hue server,hue db.hue提供所有的cdh组件的shell界面的接口.你可以在hue编写mr,查看修改hdfs的文件 ...