这是一道比较经典的DP,两串基因序列包含A、C、G、T,每两个字母间的匹配都会产生一个相似值,求基因序列(字符串)匹配的最大值。
这题有点像求最长公共子序列。只不过把求最大长度改成了求最大的匹配值。用二维数组S[i][j]记录字符串a中的前i个字符与字符串b中的前j个字符匹配所产生的最大值。假如已知AG和GT的最大匹配值,AGT和GT的最大匹配值,AG和GTT的最大匹配值,求AGT和GTT的最大匹配值,这个值是AG和GT的最大匹配值加上T 和T的匹配值,AGT和GT的最大匹配值加上T 和-的匹配值,AG和GTT的最大匹配值加上-和T的匹配值中的最大值,所以状态转移方程:
S[i][j] = max(S[i-1][j-1]+data(b[i-1],a[j-1]),S[i][j-1]+data('-',a[j-1]),S[i-1][j]+data('-',b[i-1]));
| Null | A | G | T | G | A | T | G |
Null |
| -3 | -5 | -6 | -8 | -11 | -12 | -14 |
G | -2 | -2 | 2 | 1 | -1 | -4 | -5 | -7 |
T | -3 | -3 | 1 | 7 | 5 | 2 | 1 | -1 |
T | -4 | -4 | 0 | 6 | 5 | 4 | 7 | 5 |
A | -7 | 1 | -1 | 3 | 4 | 10 | 9 | 7 |
G | -9 | -1 | 6 | 5 | 8 | 8 | 8 | 14 |
第0行,第0列表示null和字符串匹配情况,结果是’-’和各个字符的累加:
for(i=1;i<=an;i++)
S[0][i] = S[0][i-1]+data('-',a[i-1]);
for(i=1;i<=bn;i++)
S[i][0] = S[i-1][0]+data('-',b[i-1]);
S[an][bn]即为所求结果。