洛谷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个石头,要求在 ...
随机推荐
- CentOS 7下用firewall-cmd控制端口与端口转发
# 将80端口的流量转发至192.168.0.1的8080端口 1.firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toad ...
- intellij idea设置打开多个文件显示在多行tab上
- webview在compileSdkVersion 大于等于23 android6.0以上系统执行js代码异常,但是在compileSdkVersion小于23 android6.0以下系统却执行正常问题
问题分析: 在compileSdkVersion>=23 android6.0以上webview.loadUrl用这个方法执行js时会将js中的一些代码当做特殊字符处理, 比如js中var t= ...
- 第十一篇 深入Python的dict和set(二)
- Bugku-CTF分析篇-日志审计(请从流量当中分析出flag)
日志审计 请从流量当中分析出flag
- 【visio】跨职能流程图
归属于 流程图类别 相比于普通流程图,突出了参与流程的组织.部门之间的联系,形式化地说,它突出的是参与流程的对象之间的联系. 它除了表达基本流程,同时也能展示每个每个流程的归属方,让每个对象明确知道自 ...
- mescroll.js简单的上拉加载、下拉刷新插件,带完整注释
声明:本插件模仿自mescroll.js,随手所作,仅以注释提供思路,只实现了部分效果,且没有考虑兼容,有兴趣的朋友随意一看.api大家可参考mescroll.js API汇总一文. demo:点我下 ...
- go基础_控制语句
if控制语句 说明:(1)if后面的条件语句不用加括号 (2)if后面可以跟一个简单的初始化语句,并以分号分割,初始化语句中的变量的作用域是整个if语句块 (3)if语句的条件语句需要尽量简单 (4) ...
- bit Buffer
在音频流解析过程中,常常会涉及到顺序读取某些bit的操作. #include<stdio.h> typedef struct _BIT_BUF { unsigned char buffer ...
- Python3问题TypeError: object() takes no parameters
1. Python中关键字变量和特殊函数,都是以__xxx__来表示的 初学Python的朋友,需要注意其中变量名中前后是有两个下划线(_)的,如果不注意,调用内部关键字变量和特殊函数时,将会出现错误 ...