zoukankan      html  css  js  c++  java
  • P1140 相似基因

    P1140 相似基因

    题目背景

    大家都知道,基因可以看作一个碱基对序列。它包含了4种核苷酸,简记作A,C,G,T。生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物。

    在一个人类基因工作组的任务中,生物学家研究的是:两个基因的相似程度。因为这个研究对疾病的治疗有着非同寻常的作用。

    题目描述

    两个基因的相似度的计算方法如下:

    对于两个已知基因,例如AGTGATG和GTTAG,将它们的碱基互相对应。当然,中间可以加入一些空碱基-,例如:

    这样,两个基因之间的相似度就可以用碱基之间相似度的总和来描述,碱基之间的相似度如下表所示:

    那么相似度就是:(-3)+5+5+(-2)+(-3)+5+(-3)+5=9。因为两个基因的对应方法不唯一,例如又有:

    相似度为:(-3)+5+5+(-2)+5+(-1)+5=14。规定两个基因的相似度为所有对应方法中,相似度最大的那个。

    输入输出格式

    输入格式:

    共两行。每行首先是一个整数,表示基因的长度;隔一个空格后是一个基因序列,序列中只含A,C,G,T四个字母。1<=序列的长度<=100。

    输出格式:

    仅一行,即输入基因的相似度。

    输入输出样例

    输入样例#1:
    7 AGTGATG
    5 GTTAG
    
    输出样例#1:
    14

     

    分析:

    洛谷题解,说的够详细了我就不自己写了
     

    首先,这是一道DP,类似最长公共子序列,f[i,j]可从f[i-1,j-1],f[i-1,j],f[i,j-1]转移过来。

    f[i][j]:字符串s1的前i个与字符串s2的前j个匹配所能达到的最大匹配值(不计算空碱基)

    伪代码:f[i][j]=max(f[i][j],f[i-1][j]+(s2[j]与空碱基匹配的值),f[i][j-1]+(s1[i]与空碱基匹配的值),f[i-1][j-1]+(s1[i]与s2[j]匹配值))

    S1: A G T G A T G

    i : 1 2 3 4 5 6 7

    S2: G T T A G

    j : 1 2 3 4 5

    当i=3,j=3时 ,(前面四个字符中的空碱基省略不写,这里代表将前四个字符匹配好后能得到的最大值)

    1. S1: A G + T

    S2: G T + T

    2. S1: A G + _(空碱基)

    S2: G T + T

    3. S1: A G + T

    S2: G T + _(空碱基)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int l1,l2,a[110],b[110];
     4 char s1[110],s2[110];
     5 int f[110][110];
     6 int p[6][6]=     //初始化碱基之间的配对值
     7 {
     8     {0},
     9     {0,5,-1,-2,-1,-3},
    10     {0,-1,5,-3,-2,-4},
    11     {0,-2,-3,5,-2,-2},
    12     {0,-1,-2,-2,5,-1},
    13     {0,-3,-4,-2,-1,0}
    14 };
    15 int fuck(char c)//将字符转化为序号
    16 {
    17     if(c=='A') return 1;
    18     if(c=='C') return 2;
    19     if(c=='G') return 3;
    20      return 4;
    21 }
    22 int main()
    23 {
    24     //freopen("acgt.in","r",stdin);//文件输入输出
    25     //freopen("acgt.out","w",stdout);//同上
    26     int t,i,j;
    27     scanf("%d%s%d%s",&l1,s1+1,&l2,s2+1);//输入(输入完后s1,s2的第一个字符在s[1]的位置)
    28     for(i=1;i<=l1;i++)
    29         for(j=1;j<=l2;j++)
    30             f[i][j]=INT_MIN;//将f数组初始化为一个很小的值
    31      for(i=1;i<=l1;i++)
    32         a[i]=fuck(s1[i]);//将s1中的字符转化为序号存在数组a中
    33     for(i=1;i<=l2;i++)
    34         b[i]=fuck(s2[i]);//将s2中的字符转化为序号存在数组b中
    35     for(i=1;i<=l1;i++)//将f数组赋初值
    36         f[i][0]=f[i-1][0]+p[a[i]][5];
    37     for(i=1;i<=l2;i++)//同上
    38         f[0][i]=f[0][i-1]+p[b[i]][5];
    39     for(i=1;i<=l1;i++)//DP方程(上面有讲)
    40         for(j=1;j<=l2;j++)
    41         {
    42             f[i][j]=max(f[i][j],f[i][j-1]+p[b[j]][5]);
    43             f[i][j]=max(f[i][j],f[i-1][j]+p[a[i]][5]);
    44             f[i][j]=max(f[i][j],f[i-1][j-1]+p[a[i]][b[j]]);
    45         }
    46     printf("%d
    ",f[l1][l2]);//输出
    47     return 0;
    48 }
     
  • 相关阅读:
    Dynamic 365 中创建编码规则
    程序员和产品经理之间的恩怨情仇
    Scrum已经俘获中国开发者的心? ——从《2017年开发者调查报告》看真相!
    不懂营销的产品经理不是好的产品经理
    关于程序猿之间丧心病狂的鄙视链——编辑器篇
    国内五款好用的开源建站系统
    程序员听到bug后的N种反应,太形象了
    功能至上!国内外最实用的协作类软件盘点
    关于程序员之间丧心病狂的鄙视链——编程语言篇
    结对编程体会
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7442265.html
Copyright © 2011-2022 走看看