传送门

参考资料

  [1]:https://www.cnblogs.com/real-l/p/9712029.html

  [2]:https://www.luogu.org/problemnew/solution/P1140

题解

  方法一:枚举所有可能(记忆型DP)

  相关变量解释:

    m,n...................................................分别代表串1、串2的长度

    a[maxn]............................................a[i] : 串 1 的 i 位置的字母对应的数字(下标从 1 开始,并且 A->1;C->2;G->3;T->4)

    b[maxn]............................................b[i] : 串 2 的 i 位置的字母对应的数字(解释同上)

    dp[maxn][maxn]................................dp[ i ][ j ] : 串 1 的 1~i 与 串 2 的 1~j 匹配所获得的最大相似度;

    table[maxn][maxn]............................对应题干中的基因配对表

  步骤:

  (1):预处理出dp[ i ][0] , dp[0][ j ](1 ≤ i ≤ m , 1 ≤ j ≤ n)

 for(int i=;i <= m;++i)
dp[i][]=dp[i-][]+table[a[i]][]; for(int i=;i <= n;++i)
dp[][i]=dp[][i-]+table[b[i]][];

这一操作是什么意思呢?

  根据dp[][]的含义可知,dp[ i ][0]表示的是串 1 匹配到 i 字符,串2匹配到0 的最大相似度;

  串2匹配到 0 字符意味着串1的第 i 个字符匹配' - '吗,对应着table表中的table[a[ i ]][5];

  而前 i-1 个字符匹配的也是' - ',根据最大相似度的定义,所以匹配到 i 字符处的最大相似度就是

    table[a[0]][5]+table[a[1]][5]+........+table[a[ i ]][5],此处用前缀和表示;

  同理可得dp[ 0 ][ i ]得含义。

  (2):状态转移方程

    对于串1的 i 位置,串2的 j 位置时,有一下三种可能:

    ①:串1的 i 位置和 ' - ' 配对 dp[ i-1 ][ j ]+table[ a[i] ][5];

    ②:串2的 j 位置和 ' - ' 配对 dp[ i ][ j-1 ]+table[ b[j] ][5];

    ③:串1的 i 位置和串2的 j 位置配对 dp[ i-1 ][ j-1 ]+table[ a[i] ][ b[j] ];

    从中找出最大的相似度赋值给dp[ i ][ j ];

Code

 #include<iostream>
#include<cstdio>
using namespace std;
const int maxn=+; int m,n;
int dp[maxn][maxn];
int a[maxn],b[maxn];
int table[][]={
{},
{,,-,-,-,-},
{,-,,-,-,-},
{,-,-,,-,-},
{,-,-,-,,-}
};
void Solve()
{
for(int i=;i <= m;++i)
dp[i][]=dp[i-][]+table[a[i]][];
for(int i=;i <= n;++i)
dp[][i]=dp[][i-]+table[b[i]][];
for(int i=;i <= m;++i)
{
for(int j=;j <= n;++j)
{
dp[i][j]=dp[i-][j]+table[a[i]][];// 串1的 i 字符匹配 ' _ '
dp[i][j]=max(max(dp[i][j],dp[i][j-]+table[b[j]][]),dp[i-][j-]+table[a[i]][b[j]]);//串2的j字符匹配'_' 和 串1的i字符匹配串2的j字符
}
}
printf("%d\n",dp[m][n]);
}
int main()
{
scanf("%d",&m);
getchar();
for(int i=;i <= m;++i)
{
char letter=getchar();
if(letter == 'A')
a[i]=;
else if(letter == 'C')
a[i]=;
else if(letter == 'G')
a[i]=;
else
a[i]=;
}
scanf("%d",&n);
getchar();
for(int i=;i <= n;++i)
{
char letter=getchar();
if(letter == 'A')
b[i]=;
else if(letter == 'C')
b[i]=;
else if(letter == 'G')
b[i]=;
else
b[i]=;
}
Solve();
}

初始疑惑

  状态转移方程对应的三种状态没有表示处串 1 的 i 字符匹配 ' - '和串2的 j 字符匹配 ' - ' 这一情况啊。

我的理解

  对于情况① dp[ i-1 ][ j ]+table[ a[i] ][5]:

  dp[ i-1 ][ j ]的意思是, i 之前的字符和串 2 匹配过程中所能获得的最大的相似度,

  如果串1的 i 字符匹配 ' - '和串2的 j 字符匹配 ' - ' 这一情况对应的相似度最大,那么 dp[ i-1 ][ j ]就是串2的 j 字符匹配 ' - '。

  情况②同理。

分析:此题为什么可以用DP来做?

  1.满足最优子结构性质

    当串1来到 i 位置,串2来到 j 位置,如果dp[ i ][ j ]对应的解是最优解,则其之前的位置dp[1.....i-1][1........j-1]也一定是最优解。

  2.无后效性性质

    当前状态值dp[ i ][ j ]一旦确定,则此后过程的匹配就只和dp[ i ][ j ]这个状态的值有关,和之前是采取哪种匹配方式演变到当前的状态没有关系。


分割线:2019.6.11

简短题解

最近在练习动规,拿出之前做的题重新做一下;

定义dp[ i ][ j ]表示串 s 的 1~i 与串 t 的 1~j 的最大匹配度;

dp[ i ][ j ]=max{ dp[ i-1 ][ j-1 ]+|s-- tj| , dp[ i-1 ][ j ]+|s-- ' - '| , dp[ i ][ j-1 ]+|t-- ' - '|  | 1 ≤ j ≤ |t| };

Code

 #include<bits/stdc++.h>
using namespace std;
#define MAX(a,b,c) max(max(a,b),c)
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=+; int n,m;
char s[maxn];
char t[maxn];
map<char ,int >f;
int g[][]=
{
{,-,-,-,-},
{-,,-,-,-},
{-,-,,-,-},
{-,-,-,,-},
{-,-,-,-}
}; int dp[maxn][maxn];
int Solve()
{
f['A']=,f['C']=,f['G']=,f['T']=; mem(dp,);
dp[][]=g[f[s[]]][];
for(int i=;i <= n;++i)
dp[i][]=dp[i-][]+g[f[s[i]]][]; dp[][]=g[f[t[]]][];
for(int j=;j <= m;++j)
dp[][j]=dp[][j-]+g[f[t[j]]][]; for(int i=;i <= n;++i)
{
for(int j=;j <= m;++j)
{
int x=f[s[i]];
int y=f[t[j]];
dp[i][j]=dp[i-][j-]+g[x][y];
dp[i][j]=MAX(dp[i][j],dp[i-][j]+g[x][],dp[i][j-]+g[y][]);
}
}
return dp[n][m];
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
scanf("%d%s",&n,s+);
scanf("%d%s",&m,t+);
printf("%d\n",Solve()); return ;
}

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

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

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

  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. python-小知识点-14

    ''' python2 python3 ''' #python2 print() print 'abc' range() xrange() 生成器 raw_input() #python3 print ...

  2. 第二次作业 对VC++6.0编译软件的评价

    首先这个软件伴随着我们很长时间了,它是我们一上大学最先接触的,也是应用相当多的一个软件,其实在最初的时候,我对编译软件的理解非常有限,觉得它能实现一个代码的功能十分神奇的一件事情,虽然彼时我们写的代码 ...

  3. Week 2 代码规范

    Question 1: 这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. My opinion: 我认为恰恰相反,这个可以提高人们的开发效率. 在团队合作当中,如果 ...

  4. 第三个spring冲刺第8天

    今天,我们忙于完成精美的背景,还有难度的具体设置,如何达到最理想化,为此我们今天主要是做了开会讨论,但还没有完全确定好结论,明天就应该能做出结论,然后修改后台的难度设置了.

  5. NFV论文集(一)

    一 文章名称:Throughput Maximization and Resource Optimization in NFV-Enabled Networks 发表时间:2017 期刊来源:ICC: ...

  6. myBatis插件(plugins)

    MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默认情况下,MyBatis 允许使用插件来拦截的方法调用包括: Executor (update, query, flushState ...

  7. FreeMaker使用HashMap

    private Map<String, Object> variables; <input type="hidden" id="tongzhisbm&q ...

  8. Bootstrap Validator使用特性,动态(Dynamic)添加的input的验证问题

    http://1000hz.github.io/bootstrap-validator/#validator-usage Validated fields By default, the valida ...

  9. 服务器RAID设置以及简单理解

    备注: 适用于测试环境,生产环境暂时未验证 1. RAID种类 最高性能的RAID0 完全拆分所有的IO 不进行校验 但是单盘损坏, 数据完全丢失 最高损耗的RAID1 损失一半的存储容量, 做镜像, ...

  10. Windows 聆听 简单使用体验

    1. 点击windows 按键 输入语音 按照操作 选择语音 并且读出那一段话. 2. 可以将windows 语音识别 添加到开始面板 3. 使用时 点击 该图标,然后点击麦克风按钮 聆听效果如图示 ...