Luogu P1140 相似基因 【dp】By cellur925

最近博客更不起来...然后又(照例)犯鼻炎了唉难受。

题目传送门

我们首先可以预处理碱基间的权值表。然后讲读入的碱基转化为数字,就变成了“数字匹配使权值最大”的问题。我们显然可以用动态规划解决。

两个序列配对上的dp状态设计相似,以前做过一道编辑距离也是类似配对的问题。

设f[i][j]表示第一个基因当前位置到了第i个碱基,第二个基因当前位置到了第j个碱基所能得到的最大相似度。

转移:lena*lenb 而且和状态也没有什么地方可以优化了。

决策:我们可以在每一次转移的时候有3种决策:

                      A串留空/B串留空/AB恰好匹配

预处理:当一个串与另一个(完全)空的串匹配时显然只有一种情况,所有状态开始由他转移而来。

1     for(int i=1;i<=lenb;i++) f[0][i]=f[0][i-1]+w[b[i]][5];
2     for(int i=1;i<=lena;i++) f[i][0]=f[i-1][0]+w[a[i]][5];

然鹅...在这被坑了,由于有负数的权值,还要再赋一个负无穷的初值,以及f[0][0]=0!!!

Code

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 int lena,lenb;
 9 int w[6][6];
10 int a[200],b[200],f[200][200];
11 char A[200],B[200];
12 
13 void init()
14 {
15     for(int i=1;i<=4;i++) w[i][i]=5;
16     w[1][2]=w[2][1]=w[1][4]=w[4][1]=w[4][5]=w[5][4]=-1;
17     w[2][3]=w[3][2]=w[1][5]=w[5][1]=-3;
18     w[1][3]=w[3][1]=w[2][4]=w[4][2]=w[3][4]=w[3][5]=w[4][3]=w[5][3]=-2;
19     w[2][5]=w[5][2]=-4;
20 }
21 int main()
22 {
23     init();
24     /*for(int i=1;i<=5;i++)
25     {
26         for(int j=1;j<=5;j++)
27             printf("%d ",w[i][j]);
28         printf("
");
29     }*/
30         
31     scanf("%d",&lena);
32     scanf("%s",A+1);
33     for(int i=1;i<=lena;i++)
34     {
35         if(A[i]=='A') a[i]=1;
36         if(A[i]=='C') a[i]=2;
37         if(A[i]=='G') a[i]=3;
38         if(A[i]=='T') a[i]=4;
39     }
40     scanf("%d",&lenb);
41     scanf("%s",B+1);
42     for(int i=1;i<=lenb;i++)
43     {
44         if(B[i]=='A') b[i]=1;
45         if(B[i]=='C') b[i]=2;
46         if(B[i]=='G') b[i]=3;
47         if(B[i]=='T') b[i]=4;
48     }
49     memset(f,128,sizeof(f));
50     f[0][0]=0;
51     for(int i=1;i<=lenb;i++) f[0][i]=f[0][i-1]+w[b[i]][5];
52  /*    for(int i=1;i<=lenb;i++)
53      printf("%d ",f[0][i]);*/ 
54     for(int i=1;i<=lena;i++) f[i][0]=f[i-1][0]+w[a[i]][5];
55     for(int i=1;i<=lena;i++)
56      for(int j=1;j<=lenb;j++)
57       {
58             f[i][j]=max(f[i][j],f[i-1][j]+w[a[i]][5]);
59             f[i][j]=max(f[i][j],f[i][j-1]+w[b[j]][5]);
60             f[i][j]=max(f[i][j],f[i-1][j-1]+w[a[i]][b[j]]);
61       }
62     printf("%d",f[lena][lenb]);
63     return 0;
64 }
View Code
原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9530670.html