简单?dp

    xiaoxiao2026-09-22  15

    链接http://www.luogu.org/problem/show?pid=1140

    题意:给你两个基因,每个基因可以两两对应,也可以一个对应空。不同的对应会得到不同的数字,求最大的对应和是多少

    解析:dp。三个dp转移方程

    1.dp[i][j] = dp[i - 1][j - 1] + match(a[i],b[j])注意此处不是max。

    2.dp[i][j] = max(dp[i][j],dp[i - 1][j] + mapp[match(a[i])][4])第i个的对应为空

    3.dp[i][j] = max(dp[i][j],dp[i][j - 1] + mapp[4][match(b[j])])第j个对应为空。

    需要进行边界处理,先把i = 0和j = 0全都对应为空的处理好、

    两个程序、

    #include <iostream> #include <cstdio> #include <cstring> #include <sstream> #include <string> #include <algorithm> #include <list> #include <map> #include <vector> #include <queue> #include <stack> #include <cmath> #include <cstdlib> using namespace std; int mapp[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,-1000000000}}; char a[105],b[105]; int dp[105][105]; int match(char c) { if(c == 'A') return 0; if(c == 'C') return 1; if(c == 'G') return 2; if(c == 'T') return 3; return 4; } int main() { // freopen("in.txt","r",stdin); int n,m; scanf("%d%s",&n,a + 1); scanf("%d%s",&m,b + 1); for(int i = 1; i <= n; i ++) { dp[i][0] = dp[i - 1][0] + mapp[match(a[i])][4];//边界处理,此处的值是与后面的处理不一样的。这种边界不能取最大值,因为它本身是没有值的,就是不是从上衣个状态转移过来的。 //如果非得要合并在一起,需要把dp初始值设为无限小。 } for(int i = 1; i <= m; i ++) { dp[0][i] = dp[0][i - 1] + mapp[4][match(b[i])]; } for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { dp[i][j] =dp[i - 1][j - 1] + mapp[match(a[i])][match(b[j])]; dp[i][j] = max(dp[i][j],dp[i - 1][j] + mapp[match(a[i])][4]); dp[i][j] = max(dp[i][j],dp[i][j - 1] + mapp[4][match(b[j])]); } } cout<<dp[n][m] <<endl; return 0; } #include <iostream> #include <cstdio> #include <cstring> #include <sstream> #include <string> #include <algorithm> #include <list> #include <map> #include <vector> #include <queue> #include <stack> #include <cmath> #include <cstdlib> using namespace std; int mapp[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,-1000000000}}; char a[105],b[105]; int dp[105][105]; int match(char c) { if(c == 'A') return 0; if(c == 'C') return 1; if(c == 'G') return 2; if(c == 'T') return 3; return 4; } int main() { //freopen("in.txt","r",stdin); int n,m; scanf("%d%s",&n,a + 1); scanf("%d%s",&m,b + 1); for(int i = 0; i <= n; i ++) { for(int j = 0; j <= m; j ++) { dp[i][j] = -1000000000; if(i == 0 && j == 0) { dp[0][0] = 0; continue; } if(i !=0 && j != 0) dp[i][j] =dp[i - 1][j - 1] + mapp[match(a[i])][match(b[j])]; if(i != 0) dp[i][j] = max(dp[i][j],dp[i - 1][j] + mapp[match(a[i])][4]); if(j != 0) dp[i][j] = max(dp[i][j],dp[i][j - 1] + mapp[4][match(b[j])]); } } cout<<dp[n][m] <<endl; return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-1312207.html
    最新回复(0)