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. java 究竟老年代和年轻代的比例为多大合适呢?

    眼下我还没有这方面过多的经验,和切身体会 只是以我眼下的水平看来,年轻代不宜大,假设年轻代大会导致转为老年代的时候,老年代撑不下.导致full gc.回收停顿时间过长

  2. android selector设置button点击效果(具体)以及常见问题

    button的点击效果学习起来其实比較easy,此点对开发人员来说也是使用的比較频繁的一个知识点,与它相关的还有编辑框的获取焦点时改变背景颜色.选择button选择时改变字体颜色等等.这些其实都是用到 ...

  3. TFRecord —— tensorflow 下的统一数据存储格式

    tensorflow 提供了统一的数据存储格式,即 TFRecord(record 表示记录),以提高程序的可扩展性,当数据来源十分复杂时,仍能有效记录输入数据中的信息. 1. tfrecord 使用 ...

  4. 79.express里面的app.configure作用

    以下摘自 express 3.0 的 文档 app.configure([env], callback) Conditionally invoke callback when env matches ...

  5. Python3小白初体验

    三层循环嵌套,以后优化 data = { "北京":{ "a":{ ", " }, "b":{ ", &quo ...

  6. SQL try catch处理

    ALTER PROC usp_AccountTransaction @AccountNum INT, @Amount DECIMAL AS BEGIN BEGIN TRY --Start the Tr ...

  7. 联想杨天 S4130-12 win10改win7 bios参数设置

    一.进入bios 开机后按 F1 二.改bion参数 1.移动到 save& Exit  ,修改 OS optimized defaults   为“Disbled” 再 “F9” 保存 2. ...

  8. Codeforces Round #206 (Div. 2) 部分题解

    传送门:http://codeforces.com/contest/355 A:水题,特判0 int k,d; int main(){ //FIN; while(cin>>k>> ...

  9. ES6特性-对比两个值是否相等

    因为JavaScript中有语言缺陷,所以出了个Object.is()

  10. 通用查询实现方案(可用于DDD)[附源码] -- 简介

    原文:通用查询实现方案(可用于DDD)[附源码] -- 简介 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html).   [ ...