标签:
题意:给两个DNA序列,在这两个DNA序列中插入若干个‘-‘,使两段序列长度相等,对应位置的两个符号的得分规则给出,求最高得分。
解法:dp。dp[i][j]表示第一个字符串s1的前i个字符和第二个字符串s2的前j个字符对齐时的最高得分,转移方程:dp[i][j] = max{dp[i - 1][j - 1] + a[s1[i]][s2[j]], dp[i - 1] + a[s1[i]][‘-‘] + dp[i][j - 1] + a[‘-‘][s2[j]]},第一项表示对齐时s1[i]和s2[j]作为结尾,第二项表示对齐时‘-‘和s2[j]作为结尾,第三项表示对齐时s1[i]和‘-‘作为结尾。
注意dp应该以1开始,但字符串一般直接读入的话是以0开始的,因为这个样例一直过不去……调了好久……
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; int a[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 T; while(~scanf("%d", &T)) { while(T--) { string s1, s2; int len1, len2; cin >> len1 >> s1 >> len2 >> s2; for(int i = 0; i < len1; i++) if(s1[i] == ‘A‘) s1[i] = 0; else if(s1[i] == ‘C‘) s1[i] = 1; else if(s1[i] == ‘G‘) s1[i] = 2; else if(s1[i] == ‘T‘)s1[i] = 3; for(int i = 0; i < len2; i++) if(s2[i] == ‘A‘) s2[i] = 0; else if(s2[i] == ‘C‘) s2[i] = 1; else if(s2[i] == ‘G‘) s2[i] = 2; else if(s2[i] == ‘T‘) s2[i] = 3; int dp[105][105] = {0}; for(int i = 1; i <= len1; i++) dp[i][0] = dp[i - 1][0] + a[s1[i - 1]][4]; for(int i = 1; i <= len2; i++) dp[0][i] = dp[0][i - 1] + a[4][s2[i - 1]]; for(int i = 1; i <= len1; i++) for(int j = 1; j <= len2; j++) dp[i][j] = max(dp[i - 1][j - 1] + a[s1[i - 1]][s2[j - 1]], max(dp[i - 1][j] + a[s1[i - 1]][4], dp[i][j - 1] + a[4][s2[j - 1]])); printf("%d\n", dp[len1][len2]); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/Apro/p/4846347.html