poj1080——human gene function

题目大意:给出两个基因串(包含ATCG),向其中添加"-"使得两个串长度相同,5*5矩阵给出ATCG-相互匹配所代表的值,求两串基因串的最高相似度

输入:case个数n

          casei的第一个串长度 串

          casei的第二个串长度 串

输出:casei的最高相似度

分析:动态规划LCS的变形

          状态dp[i][j]:第一个串s1从字符1到i,第二个串s2从字符1到j的最大相似度

          结果:dp[n1][n2]

          初始化:dp[0][0]=0

                        dp[0][j]=dp[0][j-1]+sco[' '][s2[j]]

                        dp[i][0]=dp[i-1][0]+sco[s1[i]][' ']

          状态转移方程:dp[i][j]=max{dp[i-1][j-1]+sco[s1[i]][s2[j]],        //i和j位相匹配

                                                         dp[i-1][j]+sco[s1[i]][' '],               //i位和‘-’匹配

                                                         dp[i][j-1]+sco[' '][s2[j]]}               //j位和‘-’匹配

代码:

#include <iostream>
#include <string>
#include <algorithm>
#include <map>
using namespace std;

const int maxn=1010;
const int INF=(1<<28);

int n1,n2;
int s1[maxn],s2[maxn];
int sco[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,-INF
};
int dp[maxn][maxn];

int main(){
    int T;
    cin >> T;
    map<char,int> t;
    t['A'] = 0;
    t['C'] = 1;
    t['G'] = 2;
    t['T'] = 3;
    t[' '] = 4;
    while(T--){
        char ch;
        cin >> n1;
        for(int i = 1;i <= n1;i++){
            cin >> ch;
            s1[i] = t[ch];
        }
        cin >> n2;
        for(int i = 1;i <= n2;i++){
            cin >> ch;
            s2[i] = t[ch];
        }
        dp[0][0]=0;
        for(int i = 1;i <= n1;i++){ //注意初始化,0前面补空格才得到dp[0][i]
            dp[i][0] = dp[i - 1][0] + sco[s1[i]][4];
        }
        for(int i = 1;i <= n2;i++){
            dp[0][i] = dp[0][i - 1] + sco[s2[i]][4];
        }
        for(int i = 1;i <= n1;i++){
            for(int j = 1;j <= n2;j++){
                dp[i][j] = max(dp[i - 1][j - 1] + sco[s1[i]][s2[j]],max(dp[i - 1][j]+sco[s1[i]][4],dp[i][j - 1]+sco[4][s2[j]]));
            }
        }
        cout << dp[n1][n2] << endl;
    }
    return 0;
}

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值