题目大意:给出两个基因串(包含ATCG),向其中添加"-"使得两个串长度相同,5*5矩阵给出ATCG-相互匹配所代表的值,求两串基因串的最高相似度
输入:case个数n
casei的第一个串长度 串
casei的第二个串长度 串
输出:casei的最高相似度
分析:动态规划LCS的变形
状态dp[i][j]:第一个串s1从字符1到i,第二个串s2从字符1到j的最大相似度
结果:dp[n1][n2]
初始化:dp[0][0]=0
dp[0][j]=dp[0][j-1]+sco[' '][s2[j]]
dp[i][0]=dp[i-1][0]+sco[s1[i]][' ']
状态转移方程:dp[i][j]=max{dp[i-1][j-1]+sco[s1[i]][s2[j]], //i和j位相匹配
dp[i-1][j]+sco[s1[i]][' '], //i位和‘-’匹配
dp[i][j-1]+sco[' '][s2[j]]} //j位和‘-’匹配
代码:
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
const int maxn=1010;
const int INF=(1<<28);
int n1,n2;
int s1[maxn],s2[maxn];
int sco[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,-INF
};
int dp[maxn][maxn];
int main(){
int T;
cin >> T;
map<char,int> t;
t['A'] = 0;
t['C'] = 1;
t['G'] = 2;
t['T'] = 3;
t[' '] = 4;
while(T--){
char ch;
cin >> n1;
for(int i = 1;i <= n1;i++){
cin >> ch;
s1[i] = t[ch];
}
cin >> n2;
for(int i = 1;i <= n2;i++){
cin >> ch;
s2[i] = t[ch];
}
dp[0][0]=0;
for(int i = 1;i <= n1;i++){ //注意初始化,0前面补空格才得到dp[0][i]
dp[i][0] = dp[i - 1][0] + sco[s1[i]][4];
}
for(int i = 1;i <= n2;i++){
dp[0][i] = dp[0][i - 1] + sco[s2[i]][4];
}
for(int i = 1;i <= n1;i++){
for(int j = 1;j <= n2;j++){
dp[i][j] = max(dp[i - 1][j - 1] + sco[s1[i]][s2[j]],max(dp[i - 1][j]+sco[s1[i]][4],dp[i][j - 1]+sco[4][s2[j]]));
}
}
cout << dp[n1][n2] << endl;
}
return 0;
}