• 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
  • 相关阅读:
    腾讯QQ会员中心g_tk32算法【C#版】
    EFCore2.1中DbFirst和CodeFirst简单使用
    Asp.Net Mvc异步上传文件的方式
    Asp.Net从相对路径获取绝对路径的方法(不需要httpcontext上下文也可)
    Asp.Net分页生成页码超链接方法
    SQLServer分页查询笔记
    C#中实现对象的深拷贝
    再编写代码中报错:CS8107 C# 7.0 中不支持功能“xxxxxx”。请使用 7.1 或更高的语言版本。
    【ajax】-前台往后台传值
    [DRP]-EL表达式
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9530670.html
Copyright © 2020-2023  润新知