Description

小A最近一直在找自己的爸爸,用什么办法呢,就是DNA比对。小A有一套自己的DNA序列比较方法,其最终目标是最
大化两个DNA序列的相似程度,具体步骤如下:1.给出两个DNA序列,第一个长度为n,第二个长度为m。2.在两个序
列的任意位置插入任意多的空格,使得两个字符串长度相同3.逐位进行匹配,如果两个序列相同位置上的字符都不
是空格,假设第一个是x,第二个是y,那么他们的相似程度由d(x,y)定义。对于两个序列中任意一段极长的长度为
k的连续空格,我们定义这段空格的相似程度为g(k)=-A-B(k-1)。那么最终两个序列的相似程度就是所有的d(x,y)
加上所有的极长空格段的相似程度之和。现在小A通过某种奥妙重重的方式得到了小B的DNA序列中的一段,他想请
你帮他算一下小A的DNA序列和小B的DNA序列的最大相似程度。
 

Input

输入第1行一个字符串,表示小A的DNA序列。
输入第2行一个字符串,表示小B的DNA序列。
接下来4行,每行4个整数,用空格隔开,表示d数组,
具体顺序如下所示。
d(A,A)d(A,T)d(A,G)d(A,C)
d(T,A)d(T,T)d(T,G)d(T,C)
d(G,A)d(G,T)d(G,G)d(G,C)
d(C,A)d(C,T)d(C,G)d(C,C)
最后一行两个用空格隔开的正整数A,B,意义如题中所述。
对于所有测试点
有0<B<A≤1000,-1000≤d(x,y)≤1000,d(x,y)=d(y,x),
序列只包含{A,T,G,C}四种字符。
N+M<=3000

Output

输出共一行,表示两个序列的最大相似程度

有一个特殊的性质:
一段长度为 $k$ 的连续空格的代价为 $-A-B(k-1)$.
可以看成第一个空格的代价为 $-A$, 其它空格代价为 $-B$.
那么我们就设状态 $f[i][j],g[i][j],h[i][j]$ 分别表示 $S$ 串前 $i$ 个与 $T$ 串前 $j$ 个达到长度相同,且最后一个字符分别为 字母/字母,字母/空格,空格/字母的最大相似度.
因为不可能出现空格/空格的情况,所以就不设这个状态了.
考虑转移:
$f[i][j]$ :

  • $\leftarrow f[i-1][j-1]+d(S[i],T[j])$.

$g[i][j]$:

  • $\leftarrow g[i-1][j]-A$.
  • $\leftarrow f[i-1][j]-B$.
  • $\leftarrow h[i-1][j]-A$

$h[i][j]$:

  • $\leftarrow g[i][j-1]-A$.
  • $\leftarrow f[i][j-1]-A$.
  • $\leftarrow h[i][j-1]-B$.
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 3003
#define ll long long
#define setIO(s) freopen(s".in", "r" , stdin)
using namespace std;
char str[N];
int S[N], T[N], d[6][6], n, m;
ll f[N][N], g[N][N], h[N][N];
int id(char c)
{
if(c == 'A') return 1;
if(c == 'T') return 2;
if(c == 'G') return 3;
if(c == 'C') return 4;
}
int main()
{
// setIO("input");
int i , j, A, B;
scanf("%s", str + 1), n = strlen(str + 1);
for(i = 1; i <= n ; ++ i) S[i] = id(str[i]);
scanf("%s", str + 1), m = strlen(str + 1);
for(i = 1; i <= m ; ++ i) T[i] = id(str[i]);
for(i = 1; i <= 4 ; ++ i)
{
for(j = 1; j <= 4; ++j) scanf("%d", &d[i][j]);
}
scanf("%d%d", &A, &B);
memset(f, -63, sizeof(f)), memset(g, -63, sizeof(g)), memset(h, -63, sizeof(h));
g[1][0] = h[0][1] = - A, f[0][0] = 0;
for(i = 1; i <= n ; ++ i)
{
for(j = 1; j <= m ; ++ j)
{
f[i][j] = max(f[i - 1][j - 1], max(g[i - 1][j - 1], h[i - 1][j - 1])) + d[S[i]][T[j]];
g[i][j] = max(max(f[i - 1][j], h[i - 1][j]) - A, g[i - 1][j] - B);
h[i][j] = max(max(f[i][j - 1], g[i][j - 1]) - A, h[i][j - 1] - B);
}
}
printf("%lld\n", max(max(f[n][m], g[n][m]), h[n][m]));
return 0;
}

  

luogu 4059 [Code+#1]找爸爸 动态规划的更多相关文章

  1. loj #6250. 「CodePlus 2017 11 月赛」找爸爸

    #6250. 「CodePlus 2017 11 月赛」找爸爸 题目描述 小 A 最近一直在找自己的爸爸,用什么办法呢,就是 DNA 比对. 小 A 有一套自己的 DNA 序列比较方法,其最终目标是最 ...

  2. Luogu 1437 [HNOI2004]敲砖块 (动态规划)

    Luogu 1437 [HNOI2004]敲砖块 (动态规划) Description 在一个凹槽中放置了 n 层砖块.最上面的一层有n块砖,从上到下每层依次减少一块砖.每块砖都有一个分值,敲掉这块砖 ...

  3. 洛谷4059找爸爸(Code+第一次月赛)

    题目:https://www.luogu.org/problemnew/show/P4059 dp. 1.看出-A-B(k-1)可以理解成连续空格的第一个 -A,其余 -B: 2.把会干扰的“上一步右 ...

  4. bzoj5107: [CodePlus2017]找爸爸

    Description 小A最近一直在找自己的爸爸,用什么办法呢,就是DNA比对.小A有一套自己的DNA序列比较方法,其最终目标是最 大化两个DNA序列的相似程度,具体步骤如下:1.给出两个DNA序列 ...

  5. luogu 2943 [USACO09MAR]清理Cleaning Up 动态规划

    非常巧妙的动态规划. 你会发现每一个区间地颜色种类不能超过 $\sqrt n$, 所以可以直接枚举区间颜色种类. 令这个为 $pos[j],$ 然后考虑如何去更新这个东西就行了. Code: #inc ...

  6. 后台开发 3个题目 array_chunk, 100块钱找零钱(动态规划 dynamic programming), 双向循环链表 llist 删除节点

    1. array_chunk 实现 http://php.net/manual/en/function.array-chunk.php <?php function my_array_chunk ...

  7. 543A - Writing Code(二维动态规划)

    题意:现在要写m行代码,总共有n个文件,现在给出第i个文件每行会出现v[i]个bug,问你在bug少于b的条件下有多少种安排 分析:定义dp[i][j][k],i个文件,用了j行代码,有k个bug 状 ...

  8. 【题解】 Luogu P1541 乌龟棋总结 (动态规划)

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  9. luogu P3092 [USACO13NOV]没有找零No Change

    题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...

随机推荐

  1. 【神经网络与深度学习】【python开发】caffe-windows使能python接口使用draw_net.py绘制网络结构图过程

    [神经网络与深度学习][python开发]caffe-windows使能python接口使用draw_net.py绘制网络结构图过程 标签:[神经网络与深度学习] [python开发] 主要是想用py ...

  2. 【FFMPEG】网络流媒体协议

    目录(?)[-] RTP RTCP SRTP SRTCP RTSP RTSP 和RTP的关系 SDP RTMPRTMPS mms HLS RTP           参考文档 RFC3550/RFC3 ...

  3. 【VS开发】【图像处理】GigE和USB3 vision选择?

    [VS开发][图像处理]GigE和USB3 vision选择? 具体得看你现场的应用吧,如 现场需要的工作距离,网线可达到100m以内,USB3.0一般般的5m以内: GigE双端都有卡扣,保证了与相 ...

  4. Windows C++ 判断文件是否是图片格式的方法。

    一.通过后缀名去判断. bool IsImageByTail(const std::wstring &path) { std::wstring file_exten; size_t pos = ...

  5. Codeforces 1156F Card Bag(概率DP)

    设dp[i][j]表示选到了第i张牌,牌号在j之前包括j的概率,cnt[i]表示有i张牌,inv[i]表示i在mod下的逆元,那我们可以考虑转移,dp[i][j]=dp[i-1][j-1]*cnt[j ...

  6. 从入门到自闭之Python基础——函数初识

    1. 文件操作: 读操作: 格式:f = open("文件路径",mode = "r",encoding = "utf-8") f : 代表 ...

  7. ElasticSearch基础知识讲解

    第一节 ElasticSearch概述 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfull web接口.ElasticSea ...

  8. 使用Vim打开十六进制的文件

    So Easy 这里使用打开 Hello.class 文件为例 首先使用 vim -b Hello.class 打开文件,然后在 Vim 的命令模式下输入 :%!xxd 回车即可看见文件内容. 效果: ...

  9. 错误代码errno值的含义

    错误代码errno值的含义 查看错误代码errno是调试程序的一个重要方法.当C api函数发生异常时,一般会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义, ...

  10. Linux学习--第八天--acl、SetUID、SetGID、chattr、lsattr、sudo

    acl权限 文件只能有一个所属组 acl就是不管用户什么组了,直接针对某个文件给他特定权限. acl需要所在分区文件系统的支持. df -h #查看分区 dumpe2fs -h /dev/sda3 # ...