IT民工
加油!

现在给出两个碱基序列,可以在两个串间插入‘-’即空白,求两串的最大相似度。最长公共子序列的变形

状态转移方程:f[i][j] = Max( f[i - 1][j] + score[dna(a[i])][4],
                            f[i][j - 1] + score[4][dna(b[j])],
                            f[i - 1][j - 1] + score[dna(a[i])][dna(b[j])])

/*Accepted    216K    0MS    C++    1329B    2012-07-23 09:19:46*/

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN = 1 << 7;
char a[MAXN], b[MAXN];
int f[MAXN][MAXN];
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 dna( char c)
{
    switch( c)
    {
        case 'A' : return 0;
        case 'C' : return 1;
        case 'G' : return 2;
        case 'T' : return 3;
        case '-' : return 4;
    }
    return 0;
}

int Max( int a, int b, int c)
{
    return max( max(a, b), c);
}

int main()
{
    int T, lena, lenb, i, j;
    scanf( "%d", &T);
    while( T --)
    {
        scanf( "%d%s%d%s", &lena, a + 1, &lenb, b + 1);
        for( i = 1; i <= lena; ++ i)
            f[i][0] = f[i - 1][0] + score[dna(a[i])][4];
        for( j = 1; j <= lenb; ++ j)
            f[0][j] = f[0][j - 1] + score[4][dna(b[j])];
        for(i = 1; i <= lena; ++ i)
            for( j = 1; j <= lenb; ++ j)
            {
                f[i][j] = Max( f[i - 1][j] + score[dna(a[i])][4],
                            f[i][j - 1] + score[4][dna(b[j])],
                            f[i - 1][j - 1] + score[dna(a[i])][dna(b[j])]);
            }
        printf( "%d\n", f[lena][lenb]);
    }
    return 0;
}

 

posted on 2012-07-23 09:37  找回失去的  阅读(149)  评论(0编辑  收藏  举报