题意:给你两个基因序列,你可以添加-,使得这两个序列相等且匹配值最大,匹配值计算如下:
思路:跟LCS相似,设置dp方程,dp【i】【j】代表a字符串匹配到i,b字符串匹配到j时,最大的匹配值。
那么如果a【i】和b【j】匹配,dp【i】【j】 = dp【i-1】【j-1】 + val(a[i],b[j]);
如果a[i] 和 ’ - ‘匹配,dp [ i ] [ j ] = dp [ i - 1 ] [ j ] + val ( a [ i ] , '-');
如果b[j]和’-‘匹配,dp [ i ] [ j ] = dp [ i ] [ j - 1 ] + val (' - ' , b [ j ] );
dp[ i ] [ j ] 取这三种中的最大值~
注意初始值:当i = 0是dp[ 0 ] [ j ] = dp [ 0 ] [ j - 1 ] + val ( ' - ' ,b[ j ] );
#include <cstdio>
#include<cmath>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int inf = 1e9+10;
int t[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 getid(char c)
{
if(c == 'A')return 0;
if(c == 'C')return 1;
if(c == 'G')return 2;
if(c == 'T')return 3;
if(c == '-')return 4;
}
int val(char a,char b)
{
int tt = getid(a);
int ttt = getid(b);
return t[tt][ttt];
}
char x[10004],y[10004];
int dp[10004][10004];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%s%d%s",&n,x+1,&m,y+1);
dp[0][0] = 0;
for(int i=1;i<=n;i++)
{
dp[i][0] = dp[i-1][0] + val(x[i],'-');
}
for(int i=1;i<=m;i++)
dp[0][i] = dp[0][i-1] + val(y[i],'-');
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
dp[i][j] = max(dp[i-1][j-1] + val(x[i],y[j]),
max(dp[i-1][j] + val(x[i],'-') , dp[i][j-1] + val(y[j],'-')));
}
cout<<dp[n][m]<<'\n';
}
}