P1140 相似基因-类似于LCS的动态规划

本文探讨了一种基因序列相似度计算的问题,其思路与最长公共子序列(LCS)算法相似。通过建立动态规划的递推方程,处理不同匹配情况,确保非空碱基得到匹配。程序实现中使用二维数组存储中间状态,并利用矩阵的更新策略,最终求得两个基因序列的最大相似度。
摘要由CSDN通过智能技术生成

题目链接相似基因 - 洛谷

本题的思路和最长公共子序列有相似之处,递推方程很相似

当我们,遍历到上面的i,下面的j时,设dp[i][j]为上面前i个,下面前j个匹配时的相似度。

由于i,j不一定匹配,故分为三种情况

i,j匹配 dp[i][j]=dp[i-1][[j-1] (前i-1,j-1匹配的结果)+ f(s[i],t[j]) (相似度)

i和空格匹配,j和i-1匹配,dp[i][j]=dp[i-1][j]+ f(s[i],---)(相似度)

j和空格匹配,i和j-1匹配   dp[i][j]=dp[i][j-1]+  f(---,t[j])   (相似度)

刚开始我担心的是,一旦某个位置和空格进行了匹配,那么后面的匹配势必会受到向后推移一位的影响。

而我们对于当前i,j我们这三项操作保证了前i前j个非空碱基,注意是非空都得到了匹配。当遍历到后面时,处理的也是前i1,j1的情况,而前i1-1,j1  前 i1,j1-1 ,前i1-1,j1-1已经得到了匹配,并不会受到位置推移影响。也就是说,例如,即使前i-1,j已经匹配了好多空格,但它们还是两两完成了匹配,不会把i,j推后。

和这题的递推差不多P1435 [IOI2000] 回文字串 --LCS最长公共序列_jisuanji2606414的博客-CSDN博客

#include<iostream>
#include<set>
# include<algorithm>
# include<cstring>

using namespace std;
typedef long long int ll;

int a[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,-999999999}
};

int dp[110][110];
int ss[110],tt[110];

int change(char ch)
{
    if(ch=='A')
        return 0;
    if(ch=='C')
        return 1;
    if(ch=='G')
        return 2;
    if(ch=='T')
        return 3;

}
int main()
{


    fill(dp[0],dp[0]+110*110,-999999);

    int n,m;
    cin>>n;

    string s;
    cin>>s;

    for(int i=0; i<s.length(); i++)
    {
        ss[i+1]=change(s[i]);
    }
    cin>>m;
    cin>>s;

    for(int i=0; i<s.length(); i++)
    {
        tt[i+1]=change(s[i]);
    }
    dp[0][0]=0;

    for(int i=1;i<=n;i++)
    {
        dp[i][0]=dp[0][i-1]+a[ss[i]][4];

    }

    for(int i=1;i<=m;i++)
    {
        dp[0][i]=dp[0][i-1]+a[tt[i]][4];
    }

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            dp[i][j]=max(dp[i-1][j-1]+a[ss[i]][tt[j]],dp[i-1][j]+a[ss[i]][4]);


            dp[i][j]=max(dp[i][j],dp[i][j-1]+a[tt[j]][4]);
        }
    }

    cout<<dp[n][m];



    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qinsanma and Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值