相似基因
源程序名 GENE.??? (PAS,C,CPP)
可执行文件名 GENE.EXE
输入文件名 GENE.IN
输出文件名 GENE.OUT
大家都知道,基因可以看作一个碱基对序列。它包含了 4 种核苷酸,简记作 A,C,G,T。
生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物。
在一个人类基因工作组的任务中,生物学家研究的是:两个基因的相似程度。因为这
个研究对疾病的治疗有着非同寻常的作用。两个基因的相似度的计算方法如下:
对于两个已知基因,例如 AGTGATG 和 GTTAG,将它们的碱基互相对应。当然,中间可以
加入一些空碱基-,例如:
A G T G A T – G
– G T – – T A G
这样, 两个基因之间的相似度就可以用碱基之间相似度的总和来描述,碱基之间的相似
度如下表所示:
那么相似度就是: (-3)+5+5+(-2)+(-3)+5+(-3)+5=9。因为两个基因的对应方法不唯一,
例如又有:
A G T G A T G
– G T T A – G
相似度为: (-3)+5+5+(-2)+5+(-1)+5=14。规定两个基因的相似度为所有对应方法中,
相似度最大的那个。
输入
共两行。每行首先是一个整数,表示基因的长度;隔一个空格后是一个基因序列,序
列中只含 A,C,G,T 四个字母。 1<=序列的长度<=100。
输出
仅一行,即输入基因的相似度。
样例
GENE.IN
7 AGTGATG
5 GTTAG
GENE.OUT
14
分析:
一般dp,将图中数值打入b数组中。
状态转移为:f[i,j](表示第1个字符串的前i位与第2个字符串的前j位所能得到的最大相似度)
动态转移方程:f[i,j]:=max{a[i-1,j]+b[f(s1[i]),5],a[i,j-1]+b[5,f(s2[j])],a[i-1,j-1]+b[f(s1[i]),f(s2[j])]}
代码;
const
c:array [1..25] of longint=(5,-1,-2,-1,-3,-1,5,-3,-2,-4,-2,-3,5,-2,-2,-1,-2,-2,5,-1,-3,-4,-2,-1,0);
var
a:array [0..200,0..200] of longint;
b:array [1..5,1..5] of longint;
i,j,m,n,x,y,ans:longint;
s1,s2:string;
function f(ch:char):longint;
begin
if ch=’A’ then exit(1);
if ch=’C’ then exit(2);
if ch=’G’ then exit(3);
if ch=’T’ then exit(4);
end;
function max(x,y:longint):longint;
begin
if x>y then
exit(x);
exit(y);
end;
begin
assign(input,’gene.in’);
assign(output,’gene.out’);
reset(input);
rewrite(output);
for i:=1 to 5 do
for j:=1 to 5 do
b[i,j]:=c[i*5+j-5];
readln(n,s1);
readln(m,s2);
delete(s1,1,1);
delete(s2,1,1);
ans:=-10000000;
a[0,0]:=0;
for i:=1 to n do
a[0,i]:=b[5,f(s2[i])]+a[0,i-1];
for i:=1 to m do
a[i,0]:=b[f(s1[i]),5]+a[i-1,0];
for i:=1 to n do
for j:=1 to m do
begin
a[i,j]:=a[i-1,j]+b[f(s1[i]),5];
a[i,j]:=max(a[i,j-1]+b[5,f(s2[j])],a[i,j]);
a[i,j]:=max(a[i,j],a[i-1,j-1]+b[f(s1[i]),f(s2[j])]);
end;
writeln(a[n,m]);
close(input);
close(output);
end.