设两个字符串为a,b
dp[i][j]表示a[1]到a[i]和b[1]到b[j]的最大匹配度。
线性递推过去,dp[i][j]有3种情况:
dp[i-1][j-1]+m[i][j];
dp[i][j-1]+d[j];
dp[i-1][j]+d[i];
对应不放空白,上面放空白,下面放空白,m表示矩阵,d表示第i个字母和空白的匹配值。
注意初始化时,dp[0][0~len1],dp[0~len2][0]都要初始化。
代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int dp[105][105]; int m[4][4]={ {5,-1,-2,-1}, {-1,5,-3,-2}, {-2,-3,5,-2}, {-1,-2,-2,5}, }; int d[4]={-3,-4,-2,-1}; int hs(char c){ switch(c){ case 'A':return 0; case 'C':return 1; case 'G':return 2; case 'T':return 3; } } char a[105],b[105]; int main(){ int T; scanf("%d",&T); while(T--){ int l1,l2; scanf("%d%s%d%s",&l1,a+1,&l2,b+1); memset(dp,0,sizeof(dp)); dp[0][0]=0; for(int i=1;i<=l2;i++){ dp[0][i]=dp[0][i-1]+d[hs(b[i])]; } for(int i=1;i<=l1;i++){ dp[i][0]=dp[i-1][0]+d[hs(a[i])]; } for(int i=1;i<=l1;i++){ for(int j=1;j<=l2;j++){ int x=hs(a[i]),y=hs(b[j]); int tmp=dp[i-1][j-1]+m[x][y]; tmp=max(dp[i-1][j]+d[x],tmp); tmp=max(dp[i][j-1]+d[y],tmp); dp[i][j]=tmp; } } printf("%d\n",dp[l1][l2]); } return 0; }