题目思路:首先使用邻接矩阵存贮碱基对的相似信息,dp[i][j]表示使用字符串a中的前i个碱基、使用字符串b中的前j个碱基进行匹配的最大相似信息。
很明显dp[i][j]可由dp[i][j-1](b[j]匹配空碱基),dp[i-1][j](a[i]匹配空碱基),dp[i-1][j-1](a[i]匹配b[j])转移而来,所以状态转移方程为:dp[i][j] = max(dp[i][j],dp[i-1][j]+Map[a[i]][4],dp[i][j-1]+Map[b[j]][4],dp[i-1][j-1]+Map[a[i]][b[j]])。
#include <iostream> #include <algorithm> #include <string.h> #include <vector> #include <math.h> #include <stdio.h> #include <stack> #define LL long long using namespace std; const int Map[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 main() { int n,m; string s1,s2; int a[105],b[105],dp[105][105]; cin >> n >> s1; cin >> m >> s2; for(int i=0;i<n;i++) { if(s1[i]=='A') a[i+1] = 0; else if(s1[i]=='C') a[i+1] = 1; else if(s1[i]=='G') a[i+1] = 2; else a[i+1] = 3; } for(int i=0;i<m;i++) { if(s2[i]=='A') b[i+1] = 0; else if(s2[i]=='C') b[i+1] = 1; else if(s2[i]=='G') b[i+1] = 2; else b[i+1] = 3; } for(int i=1;i<=n;i++) dp[i][0] = dp[i-1][0] + Map[a[i]][4]; for(int j=1;j<=m;j++) dp[0][j] = dp[0][j-1] + Map[b[j]][4]; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { dp[i][j] = -999999999; dp[i][j] = max(dp[i][j],dp[i][j-1]+Map[b[j]][4]); dp[i][j] = max(dp[i][j],dp[i-1][j]+Map[a[i]][4]); dp[i][j] = max(dp[i][j],dp[i-1][j-1]+Map[a[i]][b[j]]); } } cout << dp[n][m] << endl; return 0; }