ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::
  427 随笔 :: 0 文章 :: 14 评论 :: 0 引用

Description

小A最近一直在找自己的爸爸,用什么办法呢,就是DNA比对。小A有一套自己的DNA序列比较方法,其最终目标是最
大化两个DNA序列的相似程度,具体步骤如下:1.给出两个DNA序列,第一个长度为n,第二个长度为m。2.在两个序
列的任意位置插入任意多的空格,使得两个字符串长度相同3.逐位进行匹配,如果两个序列相同位置上的字符都不
是空格,假设第一个是x,第二个是y,那么他们的相似程度由d(x,y)定义。对于两个序列中任意一段极长的长度为
k的连续空格,我们定义这段空格的相似程度为g(k)=-A-B(k-1)。那么最终两个序列的相似程度就是所有的d(x,y)
加上所有的极长空格段的相似程度之和。现在小A通过某种奥妙重重的方式得到了小B的DNA序列中的一段,他想请
你帮他算一下小A的DNA序列和小B的DNA序列的最大相似程度。

Input

输入第1行一个字符串,表示小A的DNA序列。
输入第2行一个字符串,表示小B的DNA序列。
接下来4行,每行4个整数,用空格隔开,表示d数组,
具体顺序如下所示。
d(A,A)d(A,T)d(A,G)d(A,C)
d(T,A)d(T,T)d(T,G)d(T,C)
d(G,A)d(G,T)d(G,G)d(G,C)
d(C,A)d(C,T)d(C,G)d(C,C)
最后一行两个用空格隔开的正整数A,B,意义如题中所述。
对于所有测试点
有0<B<A≤1000,-1000≤d(x,y)≤1000,d(x,y)=d(y,x),
序列只包含{A,T,G,C}四种字符。
N+M<=3000

Output

输出共一行,表示两个序列的最大相似程度
 
f[i][j][k]表示第一个串取了前i个,第二个串取了前j个,最后一个字符是(字母,字母)/(字母,空格)/(空格,字母)的最大相似程度。
#include<bits/stdc++.h>
const int M=3077,inf=0x3f3f3f3f;
char s1[M],s2[M];
int f[M][M][3],d[4][4],A,B;
int id[257];
int max(int a,int b){return a>b?a:b;}
int max(int a,int b,int c){return max(a,max(b,c));}
int main(){
    for(int i=0;i<4;++i)id["ATGC"[i]]=i;
    scanf("%s%s",s1+1,s2+1);
    for(int i=0;i<4;++i)
    for(int j=0;j<4;++j)scanf("%d",d[i]+j);
    scanf("%d%d",&A,&B);
    int l1=strlen(s1+1);
    int l2=strlen(s2+1);
    for(int i=1;i<=l1;++i)s1[i]=id[s1[i]];
    for(int i=1;i<=l2;++i)s2[i]=id[s2[i]];
    for(int i=0;i<=l1;++i){
        for(int j=0;j<=l2;++j){
            int*F=f[i][j];
            int*F1=f[i-1][j];
            int*F2=f[i][j-1];
            int*G=f[i-1][j-1];
            F[0]=i&&j?max(G[0],G[1],G[2])+d[s1[i]][s2[j]]:i||j?-inf:0;
            F[1]=i?max(max(F1[0],F1[2])-A,F1[1]-B):-inf;
            F[2]=j?max(max(F2[0],F2[1])-A,F2[2]-B):-inf;
        }
    }
    int*F=f[l1][l2];
    printf("%d\n",max(F[0],F[1],F[2]));
    return 0;
}

 

posted on 2017-11-28 01:50  nul  阅读(...)  评论(... 编辑 收藏