poj 1080 Human Gene Functions (最长公共子序列变形)

  题意:有两个代表基因序列的字符串s1和s2,在两个基因序列中通过添加"-"来使得两个序列等长;其中每对基因匹配时会形成题中图片所示匹配值,求所能得到的总的最大匹配值。

  题解:这题运用dp的解法是借用了求最长公共子序列的方法,,定义dp[i][j]代表s1以第i位结尾的串和s2以第j位结尾的串匹配时所能得到的最大匹配值;那么状态转移方程为:dp[i][j]=max( dp[i-1][j-1]+s1[i]和s2[j]的匹配值 , dp[i-1][j]+s1[i]和'-'的匹配值 , dp[i][j-1]+s2[j]和'-'的匹配值 );  另外要初始化dp[0][0]=0以及dp[i][0]和dp[0][j]的值。

  AC代码:

 1 /**
 2 *@author Wixson
 3 */
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <cmath>
 9 #include <set>
10 #include <utility>
11 #include <vector>
12 #include <map>
13 #include <queue>
14 #include <stack>
15 const int inf=0x3f3f3f3f;
16 const double PI=acos(-1.0);
17 const double EPS=1e-10;
18 using namespace std;
19 typedef long long ll;
20 typedef pair<int,int> P;
21 
22 char s1[205],s2[205];
23 int len1,len2;
24 int dp[205][205];
25 int m[5][5] = {{5,-1,-2,-1,-3},
26                 {-1,5,-3,-2,-4},
27                 {-2,-3,5,-2,-2},
28                 {-1,-2,-2,5,-1},
29                 {-3,-4,-2,-1,0}};
30 int d[500];
31 int max(int a,int b,int c)
32 {
33     return max(a,max(b,c));
34 }
35 int main()
36 {
37     //freopen("input.txt","r",stdin);
38     d['A']=0,d['C']=1,d['G']=2,d['T']=3,d['-']=4;
39     int T;
40     scanf("%d",&T);
41     while(T--)
42     {
43         scanf("%d%s",&len1,s1+1);
44         scanf("%d%s",&len2,s2+1);
45         //
46         dp[0][0]=0;
47         for(int i=1;i<=len1;i++) dp[i][0]=dp[i-1][0]+m[d[s1[i]]][d['-']];
48         for(int i=1;i<=len2;i++) dp[0][i]=dp[0][i-1]+m[d['-']][d[s2[i]]];
49         //
50         for(int i=1;i<=len1;i++)
51         {
52             for(int j=1;j<=len2;j++)
53             {
54                 dp[i][j]=max(dp[i-1][j-1]+m[d[s1[i]]][d[s2[j]]],dp[i-1][j]+m[d[s1[i]]][d['-']],dp[i][j-1]+m[d['-']][d[s2[j]]]);
55             }
56         }
57         //
58         printf("%d
",dp[len1][len2]);
59     }
60     return 0;
61 }
原文地址:https://www.cnblogs.com/geek1116/p/6544887.html