传送门

 

参考资料

  [1]:https://www.cnblogs.com/real-l/p/9712029.html

  [2]:https://www.luogu.org/problemnew/solution/P1140

题解

  方法一:枚举所有可能(记忆型DP)

  相关变量解释:

    m,n...................................................分别代表串1、串2的长度

    a[maxn]............................................a[i] : 串 1 的 i 位置的字母对应的数字(下标从 1 开始,并且 A->1;C->2;G->3;T->4)

    b[maxn]............................................b[i] : 串 2 的 i 位置的字母对应的数字(解释同上)

    dp[maxn][maxn]................................dp[ i ][ j ] : 串 1 的 1~i 与 串 2 的 1~j 匹配所获得的最大相似度;

    table[maxn][maxn]............................对应题干中的基因配对表

  步骤:

  (1):预处理出dp[ i ][0] , dp[0][ j ](1 ≤ i ≤ m , 1 ≤ j ≤ n)

1 for(int i=1;i <= m;++i)
2       dp[i][0]=dp[i-1][0]+table[a[i]][5];
3 
4 for(int i=1;i <= n;++i)
5       dp[0][i]=dp[0][i-1]+table[b[i]][5];

这一操作是什么意思呢?

  根据dp[][]的含义可知,dp[ i ][0]表示的是串 1 匹配到 i 字符,串2匹配到0 的最大相似度;

  串2匹配到 0 字符意味着串1的第 i 个字符匹配' - '吗,对应着table表中的table[a[ i ]][5]; 

  而前 i-1 个字符匹配的也是' - ',根据最大相似度的定义,所以匹配到 i 字符处的最大相似度就是

    table[a[0]][5]+table[a[1]][5]+........+table[a[ i ]][5],此处用前缀和表示;

  同理可得dp[ 0 ][ i ]得含义。

  (2):状态转移方程

    对于串1的 i 位置,串2的 j 位置时,有一下三种可能:

    ①:串1的 i 位置和 ' - ' 配对 dp[ i-1 ][ j ]+table[ a[i] ][5];

    ②:串2的 j 位置和 ' - ' 配对 dp[ i ][ j-1 ]+table[ b[j] ][5];

    ③:串1的 i 位置和串2的 j 位置配对 dp[ i-1 ][ j-1 ]+table[ a[i] ][ b[j] ];

    从中找出最大的相似度赋值给dp[ i ][ j ];

Code

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=100+50;
 5 
 6 int m,n;
 7 int dp[maxn][maxn];
 8 int a[maxn],b[maxn];
 9 int table[5][6]={
10     {0},
11     {0,5,-1,-2,-1,-3},
12     {0,-1,5,-3,-2,-4},
13     {0,-2,-3,5,-2,-2},
14     {0,-1,-2,-2,5,-1}
15 };
16 void Solve()
17 {
18     for(int i=1;i <= m;++i)
19         dp[i][0]=dp[i-1][0]+table[a[i]][5];
20     for(int i=1;i <= n;++i)
21         dp[0][i]=dp[0][i-1]+table[b[i]][5];
22     for(int i=1;i <= m;++i)
23     {
24         for(int j=1;j <= n;++j)
25         {
26             dp[i][j]=dp[i-1][j]+table[a[i]][5];// 串1的 i 字符匹配 ' _ '
27             dp[i][j]=max(max(dp[i][j],dp[i][j-1]+table[b[j]][5]),dp[i-1][j-1]+table[a[i]][b[j]]);//串2的j字符匹配'_' 和 串1的i字符匹配串2的j字符
28         }
29     }
30     printf("%d\n",dp[m][n]);
31 }
32 int main()
33 {
34     scanf("%d",&m);
35     getchar();
36     for(int i=1;i <= m;++i)
37     {
38         char letter=getchar();
39         if(letter == 'A')
40             a[i]=1;
41         else if(letter == 'C')
42             a[i]=2;
43         else if(letter == 'G')
44             a[i]=3;
45         else
46             a[i]=4;
47     }
48     scanf("%d",&n);
49     getchar();
50     for(int i=1;i <= n;++i)
51     {
52         char letter=getchar();
53         if(letter == 'A')
54             b[i]=1;
55         else if(letter == 'C')
56             b[i]=2;
57         else if(letter == 'G')
58             b[i]=3;
59         else
60             b[i]=4;
61     }
62     Solve();
63 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-14
  • 2022-12-23
  • 2021-07-28
  • 2021-08-28
  • 2021-12-21
猜你喜欢
  • 2021-07-19
  • 2022-12-23
  • 2022-12-23
  • 2021-09-21
  • 2021-07-24
  • 2021-07-16
  • 2022-12-23
相关资源
相似解决方案