思路:dp[i][j]为当长度为i和长度为j的串匹配成功时的基因相似度的最大值,注意,当基因相似度取得最大值时两个串的最后一位可能不是字母。以dp[1][1]为例子,可能会有三种匹配情况:
①-A
G-
②A-
-G
③A
G
所以状态方程为:
代码是抄添加链接描述这个的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<sstream>
using namespace std;
const int maxn = 105;
int dp[maxn][maxn];
int la, lb;
int a[maxn], b[maxn];
char c;
int v[6][6] = {
{0,0,0,0,0,0},
{0,5,-1,-2,-1,-3},
{0,-1,5,-3,-2,-4},
{0,-2,-3,5,-2,-2},
{0,-1,-2,-2,5,-1},
{0,-3,-4,-2,-1,0}
};
int main()
{
for (int i = 1; i <= maxn; i++)
{
for (int j = 1; j <= maxn; j++)
{
dp[i][j] = -2000000000; //初始化dp数组,因为答案可能为负数
}
}
scanf("%d", &la);
getchar(); //读取空格
for (int i = 1; i <= la; i++) {
scanf("%c", &c);
if (c == 'A') a[i] = 1;
if (c == 'C') a[i] = 2;
if (c == 'G') a[i] = 3;
if (c == 'T') a[i] = 4;
}
scanf("%d", &lb);
getchar(); //读取空格
for (int i = 1; i <= lb; i++) {
scanf("%c", &c);
if (c == 'A') b[i] = 1;
if (c == 'C') b[i] = 2;
if (c == 'G') b[i] = 3;
if (c == 'T') b[i] = 4;
}
for (int i = 1; i <= la; i++) //初始化边界条件
{
dp[i][0] = dp[i - 1][0] + v[a[i]][5]; //即---与ACT配对的情况
}
for (int i = 1; i <= lb; i++)
{
dp[0][i] = dp[0][i - 1] + v[5][b[i]];
}
for (int i = 1; i <= la; i++)
{
for (int j = 1; j <= lb; j++)
{
dp[i][j] = max(dp[i][j], dp[i - 1][j] + v[a[i]][5]);//第一个碱基序列加空格
dp[i][j] = max(dp[i][j], dp[i][j - 1] + v[5][b[j]]);//第二个碱基序列加空格
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + v[a[i]][b[j]]);//直接匹配
}
}
cout << dp[la][lb];
return 0;
}