动态规划,和LCS有点近似,但是我用递归加结果记录解掉了,感觉这样更直观 -_____- (其实是类LCS解法的那个一开始就没去考虑....... 面壁一下 )
dp方程见代码,应该写的比较利索了
#include#include #include #define INFINITE -9999 #define MINUS 4 int score_board[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, INFINITE}}; int score(int* gen_seq1, int len1, int* gen_seq2, int len2); void init_memory(int gen1, int gen2); int max(int a, int b, int c); int* integer_array(char* gen, int len); int memory[120][120]; int main(int argc, char** argv) { int case_count; char gen1[121], gen2[121]; int len1, len2; freopen("in.txt", "r", stdin); scanf("%d", &case_count); while(case_count --) { scanf("%d%s%d%s", &len1, gen1, &len2, gen2); init_memory(len1, len2); printf("%d\n", score(integer_array(gen1, len1), len1, integer_array(gen2, len2), len2)); } return 0; } int max(int a, int b, int c) { return a < b ? max(b, c, a) : (a > c ? a : c); } void init_memory(int len1, int len2) { int i, j; for(i = 0; i <= len1; i ++) { for(j = 0; j <= len2; j ++) { memory[i][j] = INFINITE; } } memory[0][0] = 0; } int* integer_array(char* gen, int len) { int* array = (int*)malloc(sizeof(int)*len); int i; for(i = 0; i < len; i ++) { switch(gen[i]) { case 'A': array[i] = 0; break; case 'C': array[i] = 1; break; case 'G': array[i] = 2; break; case 'T': array[i] = 3; break; } } return array; } int score(int* gen1, int len1, int* gen2, int len2) { int max_score = 0, i; if(memory[len1][len2] != INFINITE) return memory[len1][len2]; if(len1 > 0 && len2 > 0) { max_score = max( score(gen1 + 1, len1 - 1, gen2 + 1, len2 - 1) + score_board[gen1[0]][gen2[0]], score(gen1, len1, gen2 + 1, len2 - 1) + score_board[MINUS][gen2[0]], score(gen1 + 1, len1 - 1, gen2, len2) + score_board[gen1[0]][MINUS] ); } else if (len1 == 0 && len2 > 0) { for(i = 0; i < len2; i ++) { max_score += score_board[MINUS][gen2[i]]; } } else if (len2 == 0 && len1 > 0) { for(i = 0; i < len1; i ++) { max_score += score_board[gen1[i]][MINUS]; } } memory[len1][len2] = max_score; return max_score; }