zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    学习也好,科研也罢,都有内在规律。任何事物,只消抓住规律,就等于牵住牛鼻子
    赵伟国:陆资无法进入台湾紫光要到WTO控告(芯片是为了经济安全,高通找的人不是很聪明)
    小米新旗舰“翻车” 冲击中高端凸显品控短板(小米的缺点还真不少:电商、性价比、爆款、粉丝经济,说到底也都只是商业上的创新)
    WinRarHelper帮助类
    Window7下安装Ubuntu 14.04 64bit
    Kafka基本原理
    Abot爬虫和visjs
    CLR垃圾回收的设计
    NET Core全新的配置管理
    Github Atom
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9530670.html
Copyright © 2011-2022 走看看