传送门

•参考资料

  [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 ]+|si -- tj| , dp[ i-1 ][ j ]+|si -- ' - '| , dp[ i ][ j-1 ]+|tj -- ' - '|  | 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. LInux下设置账号有效时间 以及 修改用户名(同时修改用户组名和家目录)

    在linux系统中,默认创建的用户的有效期限都是永久的,但有时候,我们需要对某些用户的有效期限做个限定!比如:公司给客户开的ftp账号,用于客户下载新闻稿件的.这个账号是有时间限制的,因为是付费的.合 ...

  2. Redis常用操作-------List(列表)

    1.BLPOP key [key ...] timeout BLPOP 是列表的阻塞式(blocking)弹出原语. 它是 LPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被  ...

  3. python-知识回顾-16

    知识回顾 小数据池:int -5~256str 特殊字符,*数字20 ascii : 8位 1字节 表示1个字符unicode 32位 4个字节 表示一个字符utf- 8 1个英文 8位,1个字节 欧 ...

  4. M2阶段测试报告

    一.安全漏洞测试报告: http://files.cnblogs.com/hotsbuaa/M2-安全漏洞测试.pdf 二.全面兼容测试: http://files.cnblogs.com/hotsb ...

  5. linux内核期中总结

    20135132陈雨鑫 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  ...

  6. Linux实践四:ELF文件格式分析

    一.分析ELF文件头 二.通过文件头找到section header table,理解内容 三.通过section header table 找到各section 四.理解常见.text .strta ...

  7. WIFI探针技术

    1.WIFI 探针定义 WIFI 探针是一种能够主动识别 Android 和 IOS 设备,感知用户行为轨迹的精准数据收集前端,基于 WIFI探测技术.移动互联网和云计算等先进技术自动识别探针附近的智 ...

  8. <面向对象程序设计>课程作业一

    Github链接 在看完这次的作业要求后我整个人是混乱的,因为作业要求把不同的函数放在一个main函数中:我们之前也是进行了函数分离,但是是放在了不同的文件中.如果要改的话相当于重写(而且这两种形式其 ...

  9. 自定义组件的 v-model

    Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Bool ...

  10. 自定义控件DataPager

    在最近的一个项目中,涉及到一个自定义翻页控制的控件,下面就这一个控件做详细的说明,这个自定义控件的主要作用是对数据源进行翻页控制,比如说:“上一页.下一页.首页.末页”等相关操作,由于在一个项目中有多 ...