CODE[VS]1372:DNA

Description

为了进一步分析外星生物,专家们决定对 DNA 进行切割。
限制性核酸内切酶是基因工程中的重要的工具酶。它会识别一段碱基序列(说白了
就是只包含 ATGC 的序列)并且切割开。EcoRI 是某种限制酶的名称,它识别有某
种特性的 DNA序列,即 DNA序列双链反向排列相同的。(双链对应位碱基对要
满足碱基互补配对原则)
比如识别序列为 G A A T T C
互补链序列为 C T T A A G
第一条链从左读和第二条链从右读的是一样的。
专家们想知道某一段 DNA的序列中,具有这种特性的 DNA子序列(连续)最长
是多少,可限于智商,他们无法做出判断……于是,他们想到了你。

Input

第一行,一个整数n,表示 DNA序列的长度。
第二行,一个字符串,表示 DNA 序列的某一条链的碱基序列。

Output

输出只有一个数,为题目所求的最长特征 DNA 序列的长度。

Sample Input

7
GAATTCA

Sample Output

6

HINT

n≤ 50000

题解:

用Manacher算法求最长回文串,只不过回文的条件变为对称互补,而不是对称相等。

代码:

 1 uses math;
 2 var
 3   i,j,k,l,n,m,ans:longint;
 4   a,b:array[0..100001]of longint;
 5   ch:char;
 6 begin
 7   readln(n);
 8   for i:=1 to n do
 9   begin
10     inc(m); a[m]:=0; inc(m); read(ch);
11     case ch of
12       'G':a[m]:=-2;
13       'C':a[m]:=2;
14       'A':a[m]:=1;
15       'T':a[m]:=-1;
16     end;
17   end;
18   inc(m); a[m]:=0; a[m+1]:=maxlongint div 2;
19   a[0]:=maxlongint div 2;
20   k:=1; l:=1; b[1]:=1; ans:=1;
21   for i:=2 to m do
22   if i mod 2=1 then
23   begin
24     if l>=i then
25     b[i]:=min(b[2*k-i],l-i+1)else b[i]:=1;
26     while true do
27     begin
28       if a[i+b[i]]+a[i-b[i]]=0 then inc(b[i])
29       else break;
30     end;
31     if b[i]>ans then ans:=b[i];
32     if b[i]+i-1>l then begin l:=b[i]+i-1; k:=i; end;
33   end;
34   writeln((ans div 2)*2);
35 end.
View Code
原文地址:https://www.cnblogs.com/GhostReach/p/6257519.html