题目:https://www.luogu.org/problemnew/show/P1140
题意:
给定两串基因串(只包含ATCG),在其中插入任意个‘-’使得他们匹配。(所以一共是5种字符)
这5种字符两两之间有一个匹配数值,要求使这两个字符串的匹配值之和最大。
思路:
dp[i][j]表示匹配了s1中前i个字符和s2中前j个字符的最大匹配值。
完成s1[i]与s2[j]的匹配只有三种可能。
1.s1[i]之前已经匹配好,s2[j]配‘-’。即dp[i][j] = dp[i][j-1]+sco[s2[j]]['-']
2.s2[j]之前已经匹配好,s1[i]配‘-’。即d[i][j] = dp[i-1][j]+sco[s1[i]]['-']
3.s1[i]配s2[j]。即dp[i][j] = dp[i - 1][j - 1] + sco[s1[i]][s2[j]]
1 #include<cstdio> 2 #include<cstdlib> 3 #include<map> 4 #include<set> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<cmath> 9 #include<stack> 10 #include<queue> 11 #include<iostream> 12 13 #define inf 0x7fffffff 14 using namespace std; 15 typedef long long LL; 16 typedef pair<string, string> pr; 17 18 const int sco[5][5] = 19 { 20 {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 const int maxn = 105; 27 int len1, len2; 28 char s1[maxn], s2[maxn]; 29 int dp[maxn][maxn]; 30 31 int main() 32 { 33 scanf("%d %s", &len1, s1 + 1); 34 scanf("%d %s", &len2, s2 + 1); 35 map<char, int>mp; 36 mp['A'] = 0;mp['C'] = 1;mp['G'] = 2; mp['T'] = 3; 37 for(int i = 0; i <= len1; i++){ 38 for(int j = 0; j <= len2; j++){ 39 dp[i][j] = -2e8; 40 } 41 } 42 43 dp[0][0] = 0; 44 for(int i = 1; i <= len1; i++){ 45 dp[i][0] = dp[i - 1][0] + sco[mp[s1[i]]][4]; 46 } 47 for(int i = 1; i <= len2; i++){ 48 dp[0][i] = dp[0][i - 1] + sco[mp[s2[i]]][4]; 49 } 50 for(int i = 1; i <= len1; i++){ 51 for(int j = 1; j <= len2; j++){ 52 dp[i][j] = max(dp[i][j], dp[i][j - 1] + sco[mp[s2[j]]][4]); 53 dp[i][j] = max(dp[i][j], dp[i - 1][j] + sco[mp[s1[i]]][4]); 54 dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + sco[mp[s1[i]]][mp[s2[j]]]); 55 } 56 } 57 printf("%d\n", dp[len1][len2]); 58 return 0; 59 }