Human Gene Functions

http://poj.org/problem?id=1080

题意:已知一个人类基因的积分表,给出两个字符串,计算这两个串的最大相似程度;

思路:最长公共子序列的变形,用score[][] 表示积分值,dp[i][j]表示字符串s1[1,2,,,i]和s2[1,2,,,j]的分值,对一个dp[i][j],有三种可能:

> s1取第i个字符,s2取‘-’时,dp[i][j] = dp[i-1][j] + score[s1[i]][0];

>s1取‘-’,s2取第j个字符时,dp[i][j] = dp[i][j-1] + score[0][s2[j]];

>s1取第i个字符,s2取第j个字符时,dp[i][j] = dp[i-1][j-1] + score[s1[i]][s2[j]];

取上述三个数的最大值即是dp[i][j];

注意初始化也与LCS不同,

dp[0][0] = 0;

当i= 0时,dp[0][j] = dp[0][j-1] + score[0][s2[j]];

当j = 0时,dp[i][0] = dp[i-1][0] + score[s1[i]][0];

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 int score[5][5] ={0,-3,-4,-2,-1,
 5                  -3,5,-1,-2,-1,
 6                  -4,-1,5,-3,-2,
 7                  -2,-2,-3,5,-2,
 8                  -1,-1,-2,-2,5,};//积分表
 9 
10 int change(char ch)
11 {
12     if(ch == 'A')
13         return 1;
14     else if(ch == 'C')
15         return 2;
16     else if(ch == 'G')
17         return 3;
18     else if(ch == 'T')
19         return 4;
20 }
21 
22 int max(int a,int b,int c)
23 {
24     if(a >= b && a >= c)
25         return a;
26     if(b >= a && b >= c)
27         return b;
28     if(c >= a && c >= b)
29         return c;
30 }
31 
32 int a[110],b[110],len1,len2,dp[110][110];
33 char s1[110],s2[110];
34 
35 int main()
36 {
37     int test,i,j;
38     scanf("%d",&test);
39     while(test--)
40     {
41         memset(a,0,sizeof(a));
42         memset(b,0,sizeof(b));
43 
44         scanf("%d %s",&len1,s1);
45         scanf("%d %s",&len2,s2);
46 
47         for(i = 0; i < len1; i++)
48             a[i+1] = change(s1[i]);
49         for(i = 0; i < len2; i++)
50             b[i+1] = change(s2[i]);
51         
52         //初始化    
53         memset(dp,0,sizeof(dp));
54         dp[0][0] = 0;
55         for(int i = 1; i <= len2; i++)
56             dp[0][i] = dp[0][i-1]+score[0][b[i]];
57         for(int i = 1; i <= len1; i++)
58             dp[i][0] = dp[i-1][0]+score[a[i]][0];
59 
60         for(i = 1; i <= len1; i++)
61         {
62             for(j = 1; j <= len2; j++)
63             {
64                 int tmp1 = dp[i-1][j]+score[a[i]][0];//s1取第i个字母,s2取‘-’;
65                 int tmp2 = dp[i][j-1]+score[0][b[j]];//s1取‘-’,s2取第j个字母;
66                 int tmp3 = dp[i-1][j-1]+score[a[i]][b[j]];//s1取第i个字母,s2取第j个字母;
67                 int tmp = max(tmp1,tmp2,tmp3);
68                 dp[i][j] += tmp;
69             }
70         }
71         printf("%d
",dp[len1][len2]);
72     }
73     return 0;
74 }
View Code