洛谷P1140 相似基因

题目背景

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

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

题目描述

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

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

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

那么相似度就是:(-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。规定两个基因的相似度为所有对应方法中,相似度最大的那个。

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:

7 AGTGATG

5 GTTAG

输出样例#1:

14

Solution

显然二维dp?

设\(dp[i][j]\)表示字符串1匹配到i字符串2匹配到j(不包含'-')的最高得分

那么对于每个状态,就有三种情况,我们把这三种情况列出来,状态转移方程也就差不多了

  1. 当前i不动,由j去匹配'-'
  2. 当前j不动,有i去匹配'-'
  3. 当前i匹配当前j

为了方便转移,我们把每个配对的得分列成表

int cost[6][6]={
{0},
{0,5,-1,-2,-1,-3},
{0,-1,5,-3,-2,-4},
{0,-2,-3,5,-2,-2},
{0,-1,-2,-2,5,-1},
{0,-3,-4,-2,-1,-inf},
};

那么其实状态转移方程也就出来了

\[dp[i][j]=max(dp[i][j],dp[i][j-1]+cost[b[j]][5])
\]

\[dp[i][j]=max(dp[i][j],dp[i-1][j])+cost[a[i]][5]
\]

\[dp[i][j]=max(dp[i][j],dp[i-1][j-1]+cost[a[i]][b[j]])
\]

初始化


for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)dp[i][j]=-inf;
for(int i=1;i<=n;i++) dp[i][0]=dp[i-1][0]+cost[a[i]][5];//i不匹配
for(int i=1;i<=m;i++) dp[0][i]=dp[0][i-1]+cost[b[i]][5];//j不匹配

Code

#include<bits/stdc++.h>
using namespace std;
const int inf=2e9;
int n,m,dp[110][110],a[110],b[110];
string s1,s2;
int cost[6][6]={
{0},
{0,5,-1,-2,-1,-3},
{0,-1,5,-3,-2,-4},
{0,-2,-3,5,-2,-2},
{0,-1,-2,-2,5,-1},
{0,-3,-4,-2,-1,-inf},
};
int main()
{
ios::sync_with_stdio(0);
cin>>n>>s1>>m>>s2;
for(int i=1;i<=n;i++)
switch(s1[i-1]) {
case 'A':a[i]=1;break;
case 'C':a[i]=2;break;
case 'G':a[i]=3;break;
case 'T':a[i]=4;break;
}
for(int i=1;i<=m;i++)
switch(s2[i-1]) {
case 'A':b[i]=1;break;
case 'C':b[i]=2;break;
case 'G':b[i]=3;break;
case 'T':b[i]=4;break;
}
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)dp[i][j]=-inf;
for(int i=1;i<=n;i++) dp[i][0]=dp[i-1][0]+cost[a[i]][5];
for(int i=1;i<=m;i++) dp[0][i]=dp[0][i-1]+cost[b[i]][5];
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
dp[i][j]=max(dp[i][j],dp[i][j-1]+cost[b[j]][5]);
dp[i][j]=max(dp[i][j],dp[i-1][j]+cost[a[i]][5]);
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+cost[a[i]][b[j]]);
}
}
cout<<dp[n][m]<<endl;//目标状态
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

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

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

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

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

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

  3. 洛谷P1140 相似基因(线性DP)

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

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

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

  5. 洛谷P1140 相似基因

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

  6. 洛谷 P1140 相似基因 题解

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

  7. 【洛谷P1140 相似基因】动态规划

    分析 f[i][j] 表示 1数组的第i位和2数组的第j位匹配的最大值 f[1][1]=-2 f[2][1]=-2+5=3 f[3][1]=-2+5+5=8 三个决策: 1.由f[i-1][j-1]直 ...

  8. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  9. NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/9261079.html 题目传送门 - 洛谷P3959 题目传送门 - Vijos P2032 题意 给定一个 ...

随机推荐

  1. WinDbg命令三部曲

    WinDbg 命令三部曲:(一)WinDbg 命令手册 WinDbg 命令三部曲:(二)WinDbg SOS 扩展命令手册 WinDbg 命令三部曲:(三)WinDbg SOSEX 扩展命令手册

  2. Kubernetes学习之路(二十一)之网络模型和网络策略

    目录 Kubernetes的网络模型和网络策略 1.Kubernetes网络模型和CNI插件 1.1.Docker网络模型 1.2.Kubernetes网络模型 1.3.Flannel网络插件 1.4 ...

  3. Spring+SpringMVC+MyBatis整合优化篇

    优化篇 Spring+SpringMVC+MyBatis+easyUI整合优化篇(一)System.out.print与Log Spring+SpringMVC+MyBatis+easyUI整合优化篇 ...

  4. C#对战小游戏,持续更新(里面暂无内容,标记插眼)

    做的乱七八糟的 很明显的一点,对集合.数组.类的理解和运用   很差.很差.很差 今儿不做了,马德,头都肿大了 休息一下,捋一捋

  5. Activity猫的一生-故事解说Activity生命周期

    大家好,关于Android中Activity的生命周期,网上大多数文章基本都是直接贴图.翻译API,比较笼统含糊不清. 我就用故事来说一说: 有个人叫User,TA养了几只猫,有只猫叫Activity ...

  6. numpy 初识(二)

    针对 numpy.array(序列)的实例介绍 ndim 数组(矩阵)的维度 size 所有元素的和 数学运算(+, -) 元素个数一样,对应位置相减 加,减,乘,平方一个数,执行广播形式:即都减去一 ...

  7. python代码实现经典排序算法

    排序算法在程序中有至关重要的作用, 不同算法的时间复杂度和空间复杂度都有所区别, 这影响着程序运行的效率和资源占用的情况, 经常对一些算法多加练习, 强化吸收, 可以提高对算法的理解, 进而运用到实践 ...

  8. Java+Netty、Vue+Element-UI实现的即时通信应用 leo-im

    之前工作接触了几个开源的IM产品,再加上曾经用Netty实现过几个服务,于是就有了用Netty实现一个IM的想法,于是用业余时间写了一个IM,和喜欢Netty的程序员们分享. 考虑到方便扩展,在服务端 ...

  9. OpenGL 笔记 <2> Compiling and Linking a shader program

    Preface 这一节所有的主要内容都在一个OpenGL库文件中<LoadShaders.h> ,只需要用LoadShader()函数进行加载即可.但是由于老是出错,所以自己实现了一下,也 ...

  10. 揭秘memset与sizeof的结合使用方法

    memset与sizeof为什么经常结合起来用呢? 一.memset介绍 memset函数是C++中的一个函数,它将从给定地址开始,逐个字节刷内存,初始化它们为给定的参数. 基本用法: void * ...