luogu P1140 相似基因 序列DP

这题的题意看了20min才看懂,一直以为那个5*5的表格是上面两个序列匹配的结果推出来的,然后下面的结果是那个5*5的表格推出来的............

题目还是很简单的,有些类似LCS。dp[i][j]表示第一个序列匹配到i,第二个序列匹配到j,产生的最大相似度。然后转移的时候考虑,有三个情况,第一个序列这个位置用-和第二个序列的匹配,第二个序列这个位置用-和第一个序列的匹配,两个序列这个位置不用-,强行匹配。记忆化搜索一下就可以了。第一种就是,dp[i][j] = dp[i - 1][j] + val[-][s2[j]],第二种是dp[i][j] = dp[i][j - 1] + val[s1[i]][-],第三种是dp[i][j] = dp[i - 1][j - 1] + val[s1[i]][s2[j]]。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 int l[3];
 5 int dp[120][120],val[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}};
 6 bool vis[120][120];
 7 char s[3][120];
 8 int dfs(int x,int y)
 9 {
10     if (vis[x][y] == true || x == 0 || y == 0)
11         return dp[x][y];
12     vis[x][y] = true;
13     int res = dfs(x,y - 1) + val[4][s[2][y]];
14     res = max(res,dfs(x - 1,y) + val[s[1][x]][4]);
15     res = max(res,dfs(x - 1,y - 1) + val[s[1][x]][s[2][y]]);
16     return dp[x][y] = res;
17 }
18 int main()
19 {
20     scanf("%d",&l[1]);
21     scanf("%s",s[1] + 1);
22     scanf("%d",&l[2]);
23     scanf("%s",s[2] + 1);
24     for (int o = 1;o <= 2;o++)
25         for (int i = 1;i <= l[o];i++)
26             if (s[o][i] == 'A')
27                 s[o][i] = 0;
28             else if (s[o][i] == 'C')
29                 s[o][i] = 1;
30             else if (s[o][i] == 'G')
31                 s[o][i] = 2;
32             else 
33                 s[o][i] = 3;
34     for (int i = 1;i <= l[1];i++)
35         dp[i][0] = dp[i - 1][0] + val[s[1][i]][4];
36     for (int i = 1;i <= l[2];i++)
37         dp[0][i] = dp[0][i - 1] + val[4][s[2][i]]; 
38     printf("%d\n",dfs(l[1],l[2]));
39     return 0;
40 }

 

posted @ 2019-03-20 18:52  IAT14  阅读(156)  评论(0编辑  收藏  举报