题意:两端基因片段,各有明确的碱基序列,现有一个碱基匹配的相似度数组,设计程序使得该相似度最大。
1 //POJ1080-ZOJ1027 2 //题解:将s1碱基和s2碱基看做等长,添加一个碱基为'-',即每次都将上下碱基相互匹配后再和'-'匹配,找到最优解即可 3 //即分为三种状态: 4 // 1.s1[i]和s2[j]匹配 5 // 2.s1[i]和 '-' 匹配 6 // 3. '-' 和s2[j]匹配 7 #include <iostream> 8 #include <cstdio> 9 #include <map> 10 using namespace std; 11 12 #define MAX 105 13 #define max(x,y) ((x)>(y)?(x):(y)) 14 15 char s1[MAX], s2[MAX]; 16 int len1, len2; 17 int dp[MAX][MAX]; //dp[i][j]:s1基因的前i个碱基和s2基因的前j个碱基中的最优匹配解 18 19 map<char, int> gene; //碱基和adjust下标一一映射 20 int adjust[5][5] = { {5,-1,-2,-1,-3}, 21 {-1,5,-3,-2,-4}, 22 {-2,-3,5,-2,-2}, 23 {-1,-2,-2,5,-1}, 24 {-3,-4,-2,-1,0}}; 25 26 int main() 27 { 28 int T; 29 scanf("%d", &T); 30 31 gene['A'] = 0; gene['C'] = 1; 32 gene['G'] = 2; gene['T'] = 3; 33 gene['-'] = 4; 34 35 while (T--) 36 { 37 scanf("%d %s", &len1, s1); 38 scanf("%d %s", &len2, s2); 39 40 memset(dp, 0, sizeof(dp)); 41 42 for (int i = 1; i <= len1; i++) 43 dp[i][0] = dp[i-1][0] + adjust[gene[s1[i - 1]]][gene['-']]; //上碱基各碱基仅匹配'-'时 44 for (int j = 1; j <= len2; j++) 45 dp[0][j] = dp[0][j-1] + adjust[gene['-']][gene[s2[j - 1]]]; //下碱基各碱基仅匹配'-'时 46 47 for (int i = 1; i <= len1; i++) 48 for (int j = 1; j <= len2; j++) 49 { 50 dp[i][j] = max(dp[i][j - 1] + adjust[gene['-']][gene[s2[j - 1]]], 51 dp[i - 1][j] + adjust[gene[s1[i - 1]]][gene['-']]); //上下碱基各匹配'-'时 52 dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + adjust[gene[s1[i - 1]]][gene[s2[j - 1]]]); //上下碱基相互配对时 53 } 54 printf("%d\n", dp[len1][len2]); 55 } 56 57 58 return 0; 59 }