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. Qt creator 编译错误 :cannot find file .pro qt

    事实上问题的解决的方法非常easy:就是Qt不支持中文的路径,把源代码的路径所有改成英文就可以解决这个问题. 首先问题发生在我执行网上的样例程序时,又一次构建编译也是出错.提示: Cannot fin ...

  2. iOS使用Instrument的Leaks查找代码内存泄露

    Here are some tips for finding leaks in our project: 1. 打开Instruments调试工具控制栏, Xcode -> Open Dev T ...

  3. 阿里云aliyunlive视频直播,设置元素浮在视频上方

    视频直播,视频是可以看到了.但是还需要其他的元素,比如聊天内容,小礼物效果,观看人员列表等等.怎样让其他的元素,浮在视频上方呢? 解决方案,通过打开一个frame层,设置body的背景为透明的. 新的 ...

  4. fs路径位置与widget路径转换

    var fs = api.require('fs'); fs.exist({ path: 'fs://res/yltmusic.mp4' }, function(ret, err) { if (!re ...

  5. legend---四、菜鸟教程css3里面有教你炫酷的按钮怎么做

    legend---四.菜鸟教程css3里面有教你炫酷的按钮怎么做 一.总结 一句话总结:想学,总是有很多资料的 1. 自动居中是 margin:100px 0px;么? 自动居中是margin:100 ...

  6. 洛谷P3355 骑士共存问题

    题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置 ...

  7. Android程序测试

    一.建立测试环境 安装了Android Developer Tools (ADT) 插件的Eclipse将为你创建,构建,以及运行Android程序提供一个基于图形界面的集成开发环境.Eclipse的 ...

  8. Codefroces 852 G. Bathroom terminal

    G. Bathroom terminal Smith wakes up at the side of a dirty, disused bathroom, his ankle chained to p ...

  9. 使用iframe在手机中嵌套页面

    使用iframe嵌套网页 <iframe id="show-iframes" frameborder="0" name="showHere&qu ...

  10. CetnOS6 网络配置,主机名配置

    CetnOS6 网络配置,主机名配置 一.通过命令ifconfig -a 查看可用网络设备 二.通过网络配置文件/etc/sysconfig/network-scripts/ifcfg-eth0 配置 ...