洛谷P1140 相似基因【线性dp】

题目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 }

猜你喜欢

转载自www.cnblogs.com/wyboooo/p/10807737.html