现在给出两个碱基序列,可以在两个串间插入‘-’即空白,求两串的最大相似度。最长公共子序列的变形
状态转移方程: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; }