http://acm.hdu.edu.cn/showproblem.php?pid=1080
题目大意:基因工程,给你两段基因序列,给定任意两个字符间的相似度,可以根据需要插入减号(-)与字符匹配,求这两段基因序列的最大相似度。
算法分析:一道dp题,类似于求两个字符串的编辑距离,主要找到状态转移方程:f[i][j] = Max(f[i][j - 1] + Match('-', s2[j]), f[i - 1][j] + Match('-', s1[i]), f[i - 1][j - 1] + Match(s1[i], s2[j]));
代码
/*dp题
状态转移方程:f[i][j] = Max(f[i][j - 1] + Match('-', s2[j]), f[i - 1][j] + Match('-', s1[i]), f[i - 1][j - 1] + Match(s1[i], s2[j]));
f[i][j]表示第一个字符串的前i个字符和第二个字符串的前j个字符的最大相似度
Match(a, b) 表示字符a与字符b的相似度,程序中预处理,存入数组mat[][]中
*/
#include<stdio.h>
#define NN 102
int Max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int T, i, j, len1, len2;
char s1[NN], s2[NN];
int f[NN][NN], mat[NN][NN];
mat['A']['A'] = mat['C']['C'] = mat['G']['G'] = mat['T']['T'] = 5;
mat['A']['C'] = mat['C']['A'] = mat['A']['T'] = mat['T']['A'] = mat['-']['T'] = -1;
mat['A']['G'] = mat['G']['A'] = mat['C']['T'] = mat['T']['C'] = mat['G']['T'] = mat['T']['G'] = mat['-']['G'] = -2;
mat['-']['A'] = mat['C']['G'] = mat['G']['C'] = -3;
mat['-']['C'] = -4;
scanf("%d", &T);
while (T--){
scanf("%d%s%d%s", &len1, s1, &len2, s2);
f[0][0] = 0;
for (i = 1; i <= len1; i++)
f[i][0] = f[i - 1][0] + mat['-'][s1[i - 1]];
for (j = 1; j <= len2; j++)
f[0][j] = f[0][j - 1] + mat['-'][s2[j - 1]];
for (i = 1; i <= len1; i++){
for (j = 1; j <= len2; j++){
f[i][j] = Max(f[i][j - 1] + mat['-'][s2[j - 1]], Max(f[i - 1][j] + mat['-'][s1[i - 1]], f[i - 1][j - 1] + mat[s1[i - 1]][s2[j - 1]]));
}
}
printf("%d\n", f[len1][len2]);
}
return 0;
}