北大ACM poj1080 Human Gene Functions

来源:互联网 发布:cassandra 数据库设计 编辑:程序博客网 时间:2024/06/04 18:25
/**观察题目给出的一个最优解:AGTGATG-GTTA-G将其从某一处切开,如果左边部分的分值不是最大,那么将其进行调整,使其分值变大,则整个解分值变大,与已知的最优矛盾。所以左边部分的分值必是最大。同理,右边也是。可见满足最优子结构的性质。考虑使用DP:设两个DNA序列分别为s1,s2,长度分别为len1,len2,score为分值表。f[i,j]表示子串s1[1..i]和s2[1..j]的分值。考虑一个f[i,j],我们有:1.s1取第i个字母,s2取“-”:f[i-1,j] + score[s1[i],'-']2.s1取“-”,s2取第j个字母:f[i,j-1] + score['-',s2[j]]3.s1取第i个字母,s2取第j个字母:f[i-1,j-1] + score[s1[i],s2[j]]即f[i,j] = max(f[i-1,j] + score[s1[i],'-'], f[i,j-1] + score['-',                s2[j]], f[i-1,j-1] + score[s1[i],s2[j]]);然后考虑边界条件,这道题为i或j为0的情况。当i=j=0时,即为f[0,0],这是在计算f[1,1]时用到的,根据f[1,1] = f[0,0] + score[s1[i], s2[j]],明显有f[0,0] = 0。当i=0时,即为f[0,1..len2],有了f[0,0],可以用f[0,j] = f[0,j-1] + table['-',s2[j]]来计算。当j=0时,即为f[1..len1,0],有了f[0,0],可以用f[i,0] = f[i-1,0] + table[s1[i],'-']来计算。至于计算顺序,只要保证计算f[i,j]的时候,使用到的f[i-1,j],f[i,j-1],f[i-1,j-1]都计算出来了就行了。所谓划分阶段也就是为了达到这个目的。这样我们使用一个二重循环就可以了。*//**以 AGTGATG 和 GTTAG 为例    A   G   T   G   A   T   G    0   2   3   2   0   3   2    G   T   T   A   G    2   3   3   0   2            0       1       2       3       4       5    -------------------------------------------------                    -      --     ---    ----   -----                    G      GT     GTT    GTTA   GTTAG    0       0      -2      -3      -4      -7      -9    -------------------------------------------------            A       A      -A     --A    ---A   ---A-            -       G      GT     GTT    GTTA   GTTAG    1      -3      -2      -3      -4       1      -1    -------------------------------------------------           AG      AG     AG-    AG--   ---A-   ---AG           --      -G     -GT    -GTT   GTTAG   GTTAG    2      -5       2       1       0      -1       6    -------------------------------------------------          AGT     AGT     AGT    AGT-   AGT--  ---AGT          ---     -G-     -GT    -GTT   -GTTA  GTTAG-    3      -6       1       7       6       3       5    -------------------------------------------------         AGTG    AGTG    AGTG    AGTG   AGT-G  AGT--G         ----    -G-T    -GT-    -GTT   -GTTA  -GTTAG    4      -8      -1       5       5       4       8    -------------------------------------------------        AGTGA   AGTGA   AGTGA   AGTGA   AGTGA  AGTGA-        -----   -G-T-   -GT--   -GT-T   -GTTA  -GTTAG    5     -11      -4       2       4      10       8    -------------------------------------------------       AGTGAT  AGTGAT  AGTGAT  AGTGAT  AGTGAT  AGTGAT       ------  -G-T--  -G-T-T  -GT--T  -GTTA-  -GTTAG    6     -12      -5       1       7       9       8    -------------------------------------------------      AGTGATG AGTGATG AGTGATG AGTGATG AGTGATG AGTGATG      ------- ------G -G-T-T- -GT--T- -GTTA-- -GTTA-G    7     -14      -7      -1       5       7      14    -------------------------------------------------*/#include<stdio.h>void change(char s[],int d[],int len){    int i;    for(i=0;i<len;i++){        if(s[i]=='A')d[i]=0;        else if(s[i]=='C')d[i]=1;        else if(s[i]=='G')d[i]=2;        else if(s[i]=='T')d[i]=3;    }}int max(int a,int b,int c){    int i;    i=a>b?a:b;    return i>c?i:c;}int main(){    int score[5][5]={ 5,-1,-2,-1,-3,                     -1, 5,-3,-2,-4,                     -2,-3, 5,-2,-2,                     -1,-2,-2, 5,-1,                     -3,-4,-2,-1, 0};    int f[201][201],d1[101],d2[101];    int test,len1,len2,i,j;    char s1[101],s2[101];    int a,b,c;    //freopen("in.txt","r",stdin);    scanf("%d",&test);    while(test--){        scanf("%d%s",&len1,s1);        change(s1,d1,len1);        scanf("%d%s",&len2,s2);        change(s2,d2,len2);        for(i=0;i<=len1;i++){            for(j=0;j<=len2;j++){                if(i==0&&j){                    f[0][j]=f[0][j-1]+score[4][d2[j-1]];                }                else if(i==0&&j==0){                    f[0][0]=0;                }                else if(i&&j==0){                    f[i][0]=f[i-1][0]+score[d1[i-1]][4];                }                else{                    a=f[i-1][j]+score[d1[i-1]][4];                    b=f[i][j-1]+score[4][d2[j-1]];                    c=f[i-1][j-1]+score[d1[i-1]][d2[j-1]];                    f[i][j]=max(a,b,c);                }            }        }        printf("%d\n",f[len1][len2]);    }}

原创粉丝点击