POJ-1080 Human Gene Functions---类似LCS

题目链接:

https://cn.vjudge.net/problem/POJ-1080

题目大意:

给定两组序列,要你求出它们的最大相似度,每个字母与其他字母或自身和空格对应都有一个打分,求在这两个字符串中插入空格,让这两个字符串的匹配分数最大

解题思路:

类似LCS,以dp[i][j]表示s1前i位和s2前j位的最优解。

递推式为:

先不考虑括号

dp[i][j]只由dp[i-1][j-1]递推而来

if(s1[i] == s2[j])dp[i][j] = dp[i - 1][j - 1] + 5

else dp[i][j] = dp[i - 1][j - 1] + Map[id1][id2]此处Map[id1][id2]为s1[i]和s2[j]匹配的分数

考虑括号

dp[i][j]在原来基础上可以由dp[i-1][j]和dp[i][j-1]递推而来

由dp[i-1][j]递推而来的时候是s1[i]和空格匹配

由dp[i][j-1]递推而来的时候是空格和s2[j]匹配

dp[i][j] = max(dp[i][j],dp[i-1][j] + Map[id1][空格], dp[i][j - 1] + Map[空格][id2])

注意:

要初始化dp[0][i]和dp[j][0]的值(不能单纯的置为0,置为0是错误的),dp[0][0]=0

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<stack>
 8 #include<map>
 9 #include<sstream>
10 #define Mem(a, b) memset(a, b, sizeof(a))
11 using namespace std;
12 typedef long long ll;
13 const int INF = 1e9+7;
14 int dp[105][105];
15 int Map[5][5] =
16 {
17     5,-1,-2,-1,-3,
18     -1,5,-3,-2,-4,
19     -2,-3,5,-2,-2,
20     -1,-2,-2,5,-1,
21     -3,-4,-2,-1,0,
22 };
23 char s1[105], s2[105];
24 int main()
25 {
26     map<char, int>id;
27     id['A'] = 0;
28     id['C'] = 1;
29     id['G'] = 2;
30     id['T'] = 3;
31     id[' '] = 4;
32     int T, n, m;
33     cin >> T;
34     while(T--)
35     {
36         cin >> n >> (s1 + 1);
37         cin >> m >> (s2 + 1);
38         Mem(dp, 0);
39         for(int i = 1; i <= n; i++)
40         {
41             dp[i][0] = dp[i - 1][0] + Map[id[s1[i]]][id[' ']];
42         }
43         for(int i = 1; i <= m; i++)
44         {
45             dp[0][i] = dp[0][i - 1] + Map[id[' ']][id[s2[i]]];
46         }
47         for(int i = 1; i <= n; i++)
48         {
49             for(int j = 1; j <= m; j++)
50             {
51                 if(s1[i] == s2[j])
52                     dp[i][j] = dp[i - 1][j - 1] + 5;
53                 else
54                     dp[i][j] = dp[i - 1][j - 1] + Map[id[s1[i]]][id[s2[j]]];
55                 //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
56                 dp[i][j] = max(dp[i][j], dp[i - 1][j] + Map[id[s1[i]]][id[' ']]);
57                 dp[i][j] = max(dp[i][j], dp[i][j - 1] + Map[id[' ']][id[s2[j]]]);
58                 //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
59             }
60             //
61         }
62         cout<<dp[n][m]<<endl;
63     }
64     return 0;
65 }

 

posted @ 2018-05-08 21:09  _努力努力再努力x  阅读(131)  评论(0编辑  收藏  举报