【洛谷习题】相似基因

题目链接:https://www.luogu.org/problemnew/show/P1140


语文很重要!!!如果题目意思都不理解,怎么可能写出正解?!两个序列都可以插空位!两个序列都可以插空位!两个序列都可以插空位!

其实如果写过最长公共子序列,这道题简直就是水题(考察阅读理解)。在这里放一波最长公共子序列,对于序列s1,s2,我们定义dp[i][j]表示考虑到s1的第i个元素,s2的第j个元素所能取到的最长公共子序列的长度,枚举i,j,若s1[i]=s2[j],则他们可以作为最长公共子序列的结尾,dp[i][j]=dp[i-1][j-1]+1;反之,s[i]和s[j]不可以作为最长公共子序列的结尾,dp[i][j]=max(dp[i][j-1],dp[i-1][j])。

本题同理,只不过字符的转换、dp数组初始化等细节需要处理好。

 1 #include <cstdio>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int maxn = 105;
 7 const int match[5][5] = {{5, -1, -2, -1, -3},
 8                         {-1, 5, -3, -2, -4},
 9                         {-2, -3, 5, -2, -2},
10                         {-1, -2, -2, 5, -1},
11                         {-3, -4, -2, -1, 0}};
12 
13 int a[maxn], b[maxn], dp[maxn][maxn];
14 char s[maxn];
15 
16 inline int toInt(char c) {
17     if (c == 'A') return 0;
18     else if (c == 'C') return 1;
19     else if (c == 'G') return 2;
20     else return 3;
21 }
22 
23 int main() {
24     int al, bl;
25     scanf("%d%s", &al, s + 1);
26     for (int i = 1; i <= al; ++i) a[i] = toInt(s[i]);
27     scanf("%d%s", &bl, s + 1);
28     for (int i = 1; i <= bl; ++i) b[i] = toInt(s[i]);
29     for (int i = 1; i <= al; ++i) dp[i][0] = dp[i - 1][0] + match[a[i]][4];
30     for (int i = 1; i <= bl; ++i) dp[0][i] = dp[0][i - 1] + match[4][b[i]];
31     for (int i = 1; i <= al; ++i)
32         for (int j = 1; j <= bl; ++j) {
33             dp[i][j] = dp[i - 1][j - 1] + match[a[i]][b[j]];
34             dp[i][j] = max(dp[i][j], dp[i - 1][j] + match[a[i]][4]);
35             dp[i][j] = max(dp[i][j], dp[i][j - 1] + match[4][b[j]]);
36         }
37     printf("%d", dp[al][bl]);
38     return 0;
39 }
AC代码
原文地址:https://www.cnblogs.com/Mr94Kevin/p/9607579.html