洛谷P1140 相似基因(线性DP)
题目背景
大家都知道,基因可以看作一个碱基对序列。它包含了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。
输出格式
仅一行,即输入基因的相似度。
输入输出样例
7 AGTGATG
5 GTTAG
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)的更多相关文章
- 洛谷 P1140 相似基因 ( 线性DP || 类LCS )
题意 : 题目链接 分析 : 可以观察到给出的配对代价表中对角线部分是正数 其余的都是负数,也就是说让相同字母的匹配的越多越好 即找出 LCS 但是这里 DP 的过程需要记录一下代价 有关 LCS ...
- 洛谷P1140 相似基因 (DP)
洛谷P1140 相似基因 题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. ...
- 2018.08.16 洛谷P2029 跳舞(线性dp)
传送门 简单的线性dp" role="presentation" style="position: relative;">dpdp. 直接推一推 ...
- 洛谷P1140 相似基因【线性dp】
题目:https://www.luogu.org/problemnew/show/P1140 题意: 给定两串基因串(只包含ATCG),在其中插入任意个‘-’使得他们匹配.(所以一共是5种字符) 这5 ...
- 洛谷 P1140 相似基因(DP)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 参考资料: [1]:https://www.cnblogs.com/real-l/p/9 ...
- 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]表示 ...
- 洛谷P1140 相似基因
题目:https://www.luogu.org/problemnew/show/P1140 分析: 本题一看就知道是一道动归,其实和字串距离非常的像,只不过多了题目规定的匹配相似度罢了. 匹配的相似 ...
- 洛谷 P1140 相似基因 题解
每日一题 day23 打卡 Analysis dp[i][j]表示序列A中前i个与序列B中前j个匹配的相似度最大值 所以,dp方程很容易想到: 1.让a[i]与b[j]匹配 2.让a[i]与B序列中一 ...
- 洛谷P1052 过河【线性dp】【离散化】
题目:https://www.luogu.org/problemnew/show/P1052 题意: 青蛙要从0跳到超过$l$的地方,每一次可以跳$s$到$t$之间的任意数. 在河中有m个石头,要求在 ...
随机推荐
- 牛客网刷题总结—Day1
1.关于哈夫曼树 哈夫曼树也称最优二叉树,其n个叶子节点都是带有权值的,其节点的带权路径长度(n个叶子节点的权值*其到根节点的路径之和)最小的二叉树即为哈夫曼树. 一般的哈夫曼树不存在度为1的节点(除 ...
- unittest学习3-测试组件setup、teardown
unittest的测试用例执行时都可以设置setup.teardown,用来初始化测试开始和测试结束关闭,例如: import unittest class MyTestCase(unittest.T ...
- C#常用的form窗体属性(最大化、最小化、窗体居中)
一.窗体居中 //窗体居中 this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 二.去掉最小化.最大化 ...
- DataGridView编辑后立即更新到数据库的两种方法
DataGridView控件是微软预先写好的一个显示数据的控件,功能非常强大,可以显示来自数据库表的数据和XML等其他来源的数据. 方法一:基于DataAdapter对象创建一个CommandBuli ...
- Nexus坑人系列-license格式问题
这种情况一般出现在RMA或者新设备使用的时候.这些时候一般需要安装license,在安装完license的时候,例如我们去配置一些三层特性,例如feature eigrp等,可能会出现设备拒绝了你的命 ...
- Django模板结构优化{% include %}和{% extend %}标签
https://blog.csdn.net/xujin0/article/details/83420633
- electron-vue + element-ui构建桌面应用
最近需要用Node.js做一个桌面的应用,了解到electron可以用来做跨平台的桌面应用,而vue可以用来作为界面的解决方案,研究了一会儿如何把他们两个整合到一起使用,遇到了各种问题而放弃,毕竟作为 ...
- 共有T个硬币,其中Z个正面,F个反面,分为两堆,要如何操作使得两堆中的正面硬币数目相等。
类似题目如下(数值是可变化的) 你的面前有30个硬币,其中有10个正面朝上,20个反面朝上,混乱在一团. 要求:现在用厚布遮住你的眼睛.要你把30个硬币分成2团,每团正面朝上的硬币个数相等.问:你要怎 ...
- Linux shell sed 命令详解
详细的sed命令详解,请参考https://my.oschina.net/u/3908182/blog/1921761 sed命令常见用途 查找关键词做全局替换 查找某行的关键词做替换 查找关键字所在 ...
- Go项目结构
1. go项目工程结构 配置好工作目录后,就可以编码开发了,在这之前,我们看下go的通用项目结构,这里的结构主要是源代码相应地资源文件存放目录结构. 1.1 gopath目录 gopath目录就是我们 ...