在这里暂且把第一组基因成为组一,第二组基因为组二。
先把f[i][0]初始化:假如都为空,第i个基因的相似度。
组二同理。
为什么要初始化呢?
f[i][j]有三个来源,当其来源于f[0][j-1]或f[i-1][0]时,代表了之前的基因什么都不对应相似的最高,可能对应某个基因后相似度反而变小了。假如不初始化,则默认值为0,可造成结果增大,因为本题有负值。
f[i][j]表示组一的第i个基因与组二的第j个基因对应的最大值。
f[i][j-1] + Form[Gene_2[j]][4]:在组一的第[i][j]个位置插入空碱基,与组一的第i个对应
f[i-1][j] + Form[Gene_1[i]][4]:在组二的第[i][j]个位置插入空碱基,与组二的第j个对应
f[i-1][j-1] + Form[Gene_1[i]][Gene_2[j]]:直接对应的值
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
string t1,t2;
int Gene_1[100],Gene_2[100];
int Form[5][5]= {
{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}
};
int f[100][100];
int Compare(int a,int b) {
return Form[a][b];
}
int main() {
int Len_1,Len_2;
scanf("%d",&Len_1);
cin>>t1;
for(int i = 1; i<=Len_1; i++) {
if(t1[i-1] == 'C') {
Gene_1[i] = 1;
} else if(t1[i-1] == 'G') {
Gene_1[i] = 2;
} else if(t1[i-1] == 'T') {
Gene_1[i] = 3;
}
}
scanf("%d",&Len_2);
cin>>t2;
for(int i = 1; i<=Len_2; i++) {
if(t2[i-1] == 'C') {
Gene_2[i] = 1;
} else if(t2[i-1] == 'G') {
Gene_2[i] = 2;
} else if(t2[i-1] == 'T') {
Gene_2[i] = 3;
}
}
for(int i = 1; i<=Len_1; i++) {
for(int j = 1; j<=Len_2; j++) {
f[i][j] = -9999;
}
}
for(int i = 1; i<=Len_1; i++) {
f[i][0] = f[i-1][0] + Form[Gene_1[i]][4];
}
for(int i = 1; i<=Len_2; i++) {
f[0][i] = f[0][i-1] + Form[Gene_2[i]][4];
}
for(int i = 1; i<=Len_1; i++) {
for(int j = 1; j<=Len_2; j++) {
f[i][j] = max(f[i][j],f[i][j-1] + Form[Gene_2[j]][4]);
f[i][j] = max(f[i][j],f[i-1][j] + Form[Gene_1[i]][4]);
f[i][j] = max(f[i][j],f[i-1][j-1] + Form[Gene_1[i]][Gene_2[j]]);
}
}
cout<<f[Len_1][Len_2];
return 0;
}