POJ 1080 Human Gene Functions (类似于编辑距离)

题意:计算两个DNA碱基序列的相似度,可以插入空格来匹配任一个碱基,题目中给了任意匹配的代价。

思路:score[i][j]为下列 三者的最大值:seq1[i]与seq2[j]匹配 + score[i-1][j-1];空格与seq1[i]匹配 + score[i-1][j];空格与seq2[j]匹配 + score[i][j-1]。

初值,score,第一列表示一直用空格匹配第一个序列,第一行表示一直用空格匹配第二个序列。

代码中的map可以用一个函数代替,我没用过,所以用它试试的。

 

  
    
#include < cstdio >
#include
< map >
using namespace std;

int cost[ 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 }};

map
< char , int > m;
int score[ 104 ][ 104 ]; // DP空间
char seq1[ 104 ], seq2[ 104 ]; // 从1开始
int len1, len2;

void match(){
score[
0 ][ 0 ] = 0 ;
for ( int i = 1 ; i <= len1; ++ i)
score[i][
0 ] = score[i - 1 ][ 0 ] + cost[m[seq1[i]]][ 4 ];
for ( int j = 1 ; j <= len2; ++ j)
score[
0 ][j] = score[ 0 ][j - 1 ] + cost[m[seq2[j]]][ 4 ];
for ( int i = 1 ; i <= len1; ++ i)
for ( int j = 1 ; j <= len2; ++ j){
int max, tmp;
max
= score[i - 1 ][j - 1 ] + cost[m[seq1[i]]][m[seq2[j]]];
tmp
= score[i - 1 ][j] + cost[m[seq1[i]]][ 4 ];
if (tmp > max)
max
= tmp;
tmp
= score[i][j - 1 ] + cost[m[seq2[j]]][ 4 ];
if (tmp > max)
max
= tmp;
score[i][j]
= max;
}
}

int main(){
// freopen("in", "r", stdin);

m[
' A ' ] = 0 ;
m[
' C ' ] = 1 ;
m[
' G ' ] = 2 ;
m[
' T ' ] = 3 ;
m[
' - ' ] = 4 ;

int cases;
scanf(
" %d " , & cases);
while (cases -- ){
scanf(
" %d %s " , & len1, & seq1[ 1 ]);
scanf(
" %d %s " , & len2, & seq2[ 1 ]);
match();
printf(
" %d\n " , score[len1][len2]);
}
return 0 ;
}

 

 

 

你可能感兴趣的:(functions)