题目背景

大家都知道,基因可以看作一个碱基对序列。它包含了444种核苷酸,简记作A,C,G,TA,C,G,TA,C,G,T。生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物。

在一个人类基因工作组的任务中,生物学家研究的是:两个基因的相似程度。因为这个研究对疾病的治疗有着非同寻常的作用。

题目描述

两个基因的相似度的计算方法如下:

对于两个已知基因,例如AGTGATGAGTGATGAGTGATG和GTTAGGTTAGGTTAG,将它们的碱基互相对应。当然,中间可以加入一些空碱基-,例如:

这样,两个基因之间的相似度就可以用碱基之间相似度的总和来描述,碱基之间的相似度如下表所示:

那么相似度就是:(−3)+5+5+(−2)+(−3)+5+(−3)+5=9(-3)+5+5+(-2)+(-3)+5+(-3)+5=9(−3)+5+5+(−2)+(−3)+5+(−3)+5=9。因为两个基因的对应方法不唯一,例如又有:

相似度为:(−3)+5+5+(−2)+5+(−1)+5=14(-3)+5+5+(-2)+5+(-1)+5=14(−3)+5+5+(−2)+5+(−1)+5=14。规定两个基因的相似度为所有对应方法中,相似度最大的那个。

输入格式

共两行。每行首先是一个整数,表示基因的长度;隔一个空格后是一个基因序列,序列中只含A,C,G,TA,C,G,TA,C,G,T四个字母。1≤1 \le 1≤序列的长度≤100 \le 100≤100。

输出格式

仅一行,即输入基因的相似度。

输入输出样例

输入 #1

7 AGTGATG
5 GTTAG
输出 #1

14
首先放上一篇超棒的题解:https://www.luogu.com.cn/paste/u7l8dqnn
这是一道线性DP题,蓝书上说得好,如果一个动态规划的算法包含多个维度,但在每个维度上都具有线性变化的阶段,这同样称为线性DP。这道题一看有两个字符串,联想到另一道题“编辑距离”,可以想到要开一个二维数组来存储,即dp[i][j]表示a串的1到i个碱基与b串的1到j个碱基的相似度。状态找到后开始写转移方程。由题意得,不考虑边界的话一共有三种情况,即dp[i][j]可能等于:
1.dp[i-1][j-1]+rela(a[i],b[j]).这表示a[i]与b[j]两个碱基彼此配对,其中rela(p,q)表示碱基p和碱基q的相似度。
2.dp[i-1][j]+rela(a[i],' ').这表示a[i]与空碱基配对。这里要注意到动态规划里无后效性的概念,不用去管a的前i-1个碱基与b的前j个碱基如何配对,只需要分析眼前情况。
3.dp[i][j-1]+rela(b[j],' ').这表示b[j]与空碱基配对。
最终要在这三者中取最大就得到转移方程。输出的答案存在dp[lena][lenb]中。lena,lenb分别表示a,b串的长度。
#include <bits/stdc++.h>
using namespace std;
char a[],b[];
int lena,lenb;
int dp[][]={-}; //dp[i][j]表示a的第i个与b的第j个到之前的相似度
map<char,int>m;
int pos=;
int rela[][]=//二维数组存储碱基与碱基之间的相似度
{
{,-,-,-,-},
{-,,-,-,-},
{-,-,,-,-},
{-,-,-,,-},
{-,-,-,-,}
};
int mmax(int a,int b,int c)
{
return max(max(a,b),c);
}
int main()
{
scanf("%d%s",&lena,a);
scanf("%d%s",&lenb,b);
int i,j;
m['A']=;//字典映射碱基到对应的下标,方便获得相似度
m['C']=;
m['G']=;
m['T']=;
m[' ']=;
dp[][]=;
for(i=;i<=lena;i++)//边界只有一种情况
{
dp[i][]=dp[i-][]+rela[m[a[i-]]][];
}
for(j=;j<=lenb;j++)
{
dp[][j]=dp[][j-]+rela[][m[b[j-]]];
}
for(i=;i<=lena;i++)
{
for(j=;j<=lenb;j++)
{
if(i&&j)
{
dp[i][j]=mmax(//手写的三个数取最大的mmax函数
dp[i-][j-]+rela[m[a[i-]]][m[b[j-]]],
dp[i-][j]+rela[m[a[i-]]][],
dp[i][j-]+rela[][m[b[j-]]]
);
}
}
}
cout<<dp[lena][lenb];//输出答案。这里注意不要习惯性的写成dp[lena-1][lenb-1],再次回顾dp[i][j]的定义,是“第i个”
return ;
}


 

洛谷P1140 相似基因(线性DP)的更多相关文章

  1. 洛谷 P1140 相似基因 ( 线性DP || 类LCS )

    题意 : 题目链接 分析 :  可以观察到给出的配对代价表中对角线部分是正数 其余的都是负数,也就是说让相同字母的匹配的越多越好 即找出 LCS 但是这里 DP 的过程需要记录一下代价 有关 LCS ...

  2. 洛谷P1140 相似基因 (DP)

    洛谷P1140 相似基因 题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. ...

  3. 2018.08.16 洛谷P2029 跳舞(线性dp)

    传送门 简单的线性dp" role="presentation" style="position: relative;">dpdp. 直接推一推 ...

  4. 洛谷P1140 相似基因【线性dp】

    题目:https://www.luogu.org/problemnew/show/P1140 题意: 给定两串基因串(只包含ATCG),在其中插入任意个‘-’使得他们匹配.(所以一共是5种字符) 这5 ...

  5. 洛谷 P1140 相似基因(DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 参考资料: [1]:https://www.cnblogs.com/real-l/p/9 ...

  6. 2018.11.04 洛谷P2679 子串(线性dp)

    传送门 为什么前几年的noipnoipnoip总是出这种送分题啊? 这个直接线性dpdpdp不就完了吗? f[i][j][k][0/1]f[i][j][k][0/1]f[i][j][k][0/1]表示 ...

  7. 洛谷P1140 相似基因

    题目:https://www.luogu.org/problemnew/show/P1140 分析: 本题一看就知道是一道动归,其实和字串距离非常的像,只不过多了题目规定的匹配相似度罢了. 匹配的相似 ...

  8. 洛谷 P1140 相似基因 题解

    每日一题 day23 打卡 Analysis dp[i][j]表示序列A中前i个与序列B中前j个匹配的相似度最大值 所以,dp方程很容易想到: 1.让a[i]与b[j]匹配 2.让a[i]与B序列中一 ...

  9. 洛谷P1052 过河【线性dp】【离散化】

    题目:https://www.luogu.org/problemnew/show/P1052 题意: 青蛙要从0跳到超过$l$的地方,每一次可以跳$s$到$t$之间的任意数. 在河中有m个石头,要求在 ...

随机推荐

  1. Django项目报错: 禁止访问(403),CSRF验证失败,相应中断

    如果想要取消表单的CSRF防护,可以在模板上删除{% csrf_token %}, 并且在相应的视图函数中添加装饰器@csrf_exempt, 代码如下: from django.views.deco ...

  2. 题解 P2146 [NOI2015]软件包管理器

    P2146 [NOI2015]软件包管理器 感觉代码比其他题解更简洁qwq 树链剖分模板题 install x:将1~x的路径上的节点全部变成1(安装x需要先安装1~x) uninstall x:将x ...

  3. 题解 UVA1335 【Beijing Guards】

    UVA1335 Beijing Guards 双倍经验:P4409 [ZJOI2006]皇帝的烦恼 如果只是一条链,第一个护卫不与最后一个护卫相邻,那么直接贪心,找出最大的相邻数的和. 当变成环,贪心 ...

  4. STL顺序容器用法自我总结

    顺序容器类型:vector.deque.list.forward_list.string.array. queue(单向队列)底层也是用deque(双端队列)实现的 a.swap(b); swap(a ...

  5. 喵星之旅-狂奔的兔子-基于docker的rabbitmq安装

    docker安装参考:喵星之旅-狂奔的兔子-docker安装和基本使用 一.查询镜像名称 由于我们要安装的是有web管理页面的,不能直接拉取,需要指定版本. 登录docker仓库查询:https:// ...

  6. Linux常用命令英文全称与中文解释 (pwd、su、df、du等)

    https://blog.csdn.net/qq_40334837/article/details/83819735 Linux常用命令英文全称与中文解释 apt: Advanced Packagin ...

  7. VIM - 问题: 简单变换

    1. 概述 学习 Java 反射的时候, 碰到的简单问题 手动可以处理, 但是真的很浪费时间 想熟悉一下工具的使用 2. 题目 源 Modifier.isAbstract(int modifiers) ...

  8. 【PAT甲级】1104 Sum of Number Segments (20 分)

    题意:输入一个正整数N(<=1e5),接着输入N个小于等于1.0的正数,输出N个数中所有序列的和. AAAAAccepted code: #define HAVE_STRUCT_TIMESPEC ...

  9. angular 中引入 markdown

    ngx-markdown 是 Angular2+ 的一个第三方库,它的主要功能是将md文件转换为HTML格式,并且支持语法高亮. GITHUB地址:https://github.com/jfcere/ ...

  10. P&R 5

    Floorplan: 要做好floorplan需要掌握哪些知识跟技能? 通常,遇到floorplan问题,大致的debug步骤跟方法有哪些? 如何衡量floorplan的QA? 芯片的整体架构模块划分 ...