luogu P1140 相似基因

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/smmyy022/article/details/81940195

题解

这题和那道经典的最长相同子序列很类似,是一道简单的(?)线性dp。
仔细思考一下什么是状态,选择以及相互之间的影响。
F [ i ] [ j ] : 代表 i,j 位置为止的两段串的最大分数
转移方程 // 显然就3种选择 i,j配对 i不配对 以及 j不配对

F [ i+1 ] [ j+1 ] = max{
                F [ i ] [ j ] + points[ a[i] ] [ b[j] ] ,
                F [ i+1 ] [ j ] + points[4] [ b[j] ] ,
                F [ i ] [ j+1 ] + points[ a[i] ] [4]
}


Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <map>
#include <algorithm>
using namespace std;

int n,m;
int a[102],b[102];
int f[102][102];
int points[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} };
int main(){

    map<char,int> mm;
    mm['A'] = 0;
    mm['C'] = 1;
    mm['G'] = 2;
    mm['T'] = 3;
    cin>>n;
    char c;
    for(int i=1;i<=n;i++){
        cin>>c;
        a[i] = mm[c] ;
    }
    cin>>m;
    for(int i=1;i<=m;i++){
        cin>>c;
        b[i] = mm[c];
    }
    // 0位置预处理
    for(int i=1;i<=n;i++) f[i][0] = f[i-1][0]+points[ a[i] ][4];
    for(int i=1;i<=m;i++) f[0][i] = f[0][i-1]+points[ b[i] ][4];

    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            f[i][j] = -100;// 负值初始化 为求max
            f[i][j] = max(f[i][j], f[i-1][j]+points[4][ a[i] ] );
            f[i][j] = max(f[i][j], f[i][j-1]+points[ b[j] ][4] );
            f[i][j] = max(f[i][j], f[i-1][j-1]+points[a[i]][b[j]] );

        }
    }
    cout<<f[n][m]<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/smmyy022/article/details/81940195