引用:

用二维数组f储存第1个基因前i个与第2个基因前j个的最大匹配值

先将字符串转化为数组储存

将f初始化为一个很小的值

因为第1个基因前i个与第2个基因第0个匹配肯定是与空碱基匹配的值

首先建立一个table,存入各个基因相似度(如下)

const int tab[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}

};

接着进行一波预处理:

for(int i=1;i<=la;i++) for(int j=1;j<=lb;j++) dp[i][j]=-2e8;//设置极小值

for(int i=1;i<=la;i++)

{

if(sa[i-1]==’A’) a[i]=0;

if(sa[i-1]==’C’) a[i]=1;

if(sa[i-1]==’G’) a[i]=2;

if(sa[i-1]==’T’) a[i]=3;

}//将字符转换为表中对应的编号

for(int i=1;i<=lb;i++)

{

if(sb[i-1]==’A’) b[i]=0;

if(sb[i-1]==’C’) b[i]=1;

if(sb[i-1]==’G’) b[i]=2;

if(sb[i-1]==’T’) b[i]=3;

}//同上

然后开始动态规划:

1.(特判)因为第一/二段的1与第二/一段的0匹配时可视作与空碱基匹配,所以先进行一波预处理:

for(int i=1;i<=la;i++) dp[i][0]=dp[i-1][0]+tab[a[i]][4];

for(int i=1;i<=lb;i++) dp[0][i]=dp[0][i-1]+tab[b[i]][4];

2.接着逐个判断即可得出三条状态转移方程,取三种配对方法(1.一中插空碱基;2.二中插空碱基;3.直接配对)所得结果中最优的一种。

(上伪代码)

{ 若在第一段基因中插入空碱基相似度更优 则在第一段插入空碱基

若在第二段基因中插入空碱基相似度更优 则在第二段插入空碱基

若直接配对的相似度高于以上两者 则直接插入

for(int i=1;i<=la;i++)
for(int j=1;j<=lb;j++)
{
dp[i][j]=max(dp[i][j],dp[i][j-1]+tab[b[j]][4]);
dp[i][j]=max(dp[i][j],dp[i-1][j]+tab[a[i]][4]);
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+tab[a[i]][b[j]]);
}
} 3.最后输出结果即可。

//my ac code
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
int max(int a,int b){return a>b?a:b;}
int jianji[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 dp[105][105],l1,l2,sa[105],sb[105];
string s1,s2;
int main(){
   cin >> l1 >> s1 >> l2 >> s2;
   for(int i=1;i<=l1;i++)for(int j=1;j<=l2;j++)dp[i][j]=-520520520;
   for(int i=1;i<=l1;i++){
       if(s1[i-1]=='A')sa[i]=0;
       if(s1[i-1]=='C')sa[i]=1;
       if(s1[i-1]=='G')sa[i]=2;
       if(s1[i-1]=='T')sa[i]=3;
   }
   for(int i=1;i<=l2;i++){
       if(s2[i-1]=='A')sb[i]=0;
       if(s2[i-1]=='C')sb[i]=1;
       if(s2[i-1]=='G')sb[i]=2;
       if(s2[i-1]=='T')sb[i]=3;
   }
   for(int i=1;i<=l1;i++)dp[i][0]=dp[i-1][0]+jianji[sa[i]][4];
   for(int i=1;i<=l2;i++)dp[0][i]=dp[0][i-1]+jianji[sb[i]][4];
   for(int i=1;i<=l1;i++){
       for(int j=1;j<=l2;j++){
           dp[i][j]=max(dp[i][j],dp[i-1][j]+jianji[sa[i]][4]);
           dp[i][j]=max(dp[i][j],dp[i][j-1]+jianji[sb[j]][4]);
           dp[i][j]=max(dp[i][j],dp[i-1][j-1]+jianji[sa[i]][sb[j]]);
       }
   }
   printf("%d",dp[l1][l2]);
    return 0;
}