题目链接

首先呢,看到 A C G T 对应不同的权值,第一步就是把字母转换成数字。

我们分别对 A->1 C->2 G->3 T->4 进行标号,之后方便 \(\text{dp}\) 。

然后看到题目中对于一个范式的定义:

一个DNA序列属于范式 \(-j(j>1)\) ,只要它属于范式 \(-(j-1)\) 或者是一个范式 \(-(j-1)\) 和一个范式 \(-1\) 的连接。

那我看了半天才看懂是什么意思,简洁来说就是范式为 \(j\) 的串同时也是范式为 \(j+1\) 的串。

其实讲到现在也就是表达一个前缀和的关系。

那我们显然要把前缀和拆开,这样的话更利于我们 \(\text{dp}\) 转移。

用符合题目的思路来说就是:隔断 \(j\) 到 \(j+1\) 这两个范式之间的直升关系。

最后再做一遍前缀和恢复就好了。

考虑怎么 \(\text{dp}\) 。

我们设 \(f_{i,j,k}\) 表示到了第 \(i\) 个位置,当前位是 \(k\) ,且范式为 \(j\) 的方案数。

那么可以得到

\[f_{i,j,k} = \sum_{type = 1}^4f_{i+1,j-[k > type],type}
\]

这个也很好理解吧。

就是说我从后向前转移,枚举后一位的优先级 \(type\) 。

如果当前的优先级 \(k\) 大于后一位的优先级 \(type\) 那么范式一定加一。

这也就是为什么转移方程中会出现 \(j-[k > type]\) 。

转移完成后要记得做一次前缀和。

具体细节可以看代码。

既然 \(f_{i,j,k}\) 都求出来了,那么输出方案也不难了。

对于 \(r\) 比当前方案数多时,那就增加当前的等级,并更新 \(r\) 。

Code

#include <cstdio>
#include <iostream>
#include <algorithm> #define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout) #define quad putchar(' ')
#define Enter putchar('\n') #define int long long
const int N = 5e4 + 5; int m, k, r, a[N], f[N][15][5];
char c[N]; inline void print(int num) {
if (num == 1) putchar('A');
if (num == 2) putchar('C');
if (num == 3) putchar('G');
if (num == 4) putchar('T');
} signed main(void) {
// file("P3624");
std::cin >> m >> k >> r;
scanf("%s", c + 1);
for (int i = 1; i <= m; i++) {
if (c[i] == 'A') a[i] = 1;
if (c[i] == 'C') a[i] = 2;
if (c[i] == 'G') a[i] = 3;
if (c[i] == 'T') a[i] = 4;
}
if (a[m] != 0) {
f[m][1][a[m]] = 1;
} else {
for (int i = 1; i <= 4; i++)
f[m][1][i] = 1;
}
for (int i = m - 1; i >= 1; i--) {
if (a[i] != 0) {
for (int j = 1; j <= k; j++) {
for (int l = 1; l <= 4; l++)
f[i][j][a[i]] += f[i + 1][j - (a[i] > l)][l];
}
} else {
for (int num = 1; num <= 4; num ++) {
for (int j = 1; j <= k; j++) {
for (int l = 1; l <= 4; l++)
f[i][j][num] += f[i + 1][j - (num > l)][l];
}
}
}
}
for (int i = 1; i <= m; i++)
for (int j = 1; j <= k; j++)
for (int l = 1; l <= 4; l++)
f[i][j][l] += f[i][j - 1][l];
int last = 0;
for (int i = 1; i <= m; i++) {
if (a[i] != 0) {
print(a[i]);
if (a[i] < last) k --;
last = a[i];
} else {
int chose;
for (chose = 1; chose <= 4 && r > f[i][k - (chose < last)][chose]; chose ++)
r -= f[i][k - (chose < last)][chose];
print(chose);
if (chose < last) k --;
last = chose;
}
}
std::cout << std::endl;
return 0;
}

[APIO2008]DNA 题解的更多相关文章

  1. 4606: [Apio2008]DNA

    4606: [Apio2008]DNA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 63  Solved: 36[Submit][Status][D ...

  2. 【BZOJ4606】[Apio2008]DNA DP

    [BZOJ4606][Apio2008]DNA Description 分析如DNA序列这样的生命科学数据是计算机的一个有趣应用.从生物学的角度上说,DNA 是一种由腺嘌呤.胞嘧啶.鸟嘌呤和胸腺嘧啶这 ...

  3. 洛谷3763:[TJOI2017]DNA——题解

    https://www.luogu.org/problemnew/show/P3763 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是 ...

  4. bzoj 4606: [Apio2008]DNA【dp】

    写题五分钟读题两小时系列-- 看懂题的话不算难,然而我去看了大佬的blog才看懂题-- 题目大意是:一个原字符串,其中有一种通配符,合法串的定义是这个串(不含通配符))可以匹配原串并且这个串最多分成k ...

  5. [APIO2008]DNA

    https://zybuluo.com/ysner/note/1158123 题面 戳我 解析 我们要求出第\(r\)种方案,莫过于看其前面什么时候有\(r-1\)种方案. 于是,我们要求出每种情况的 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. HDU1560 DNA sequence(IDA*)题解

    DNA sequence Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  8. 题解【loj537】「LibreOJ NOIP Round #1」DNA 序列

    题目描述 \(NOIP\)复赛之前\(HSD\)桑进行了一项研究,发现人某条染色体上的一段\(DNA\)序列中连续的\(k\)个碱基组成的碱基序列与做题的 \(AC\) 率有关!于是他想研究一下这种关 ...

  9. Leetcode:Repeated DNA Sequences详细题解

    题目 All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: " ...

随机推荐

  1. python基础-基本数据类型(三)

    一.散列类型 散列类型用来表示无序的集合类型 1.集合(set) Python中的集合与数学符号中的集合类似,都是用来表示无序不重复元素的集合. 1.1 集合的定义 集合使用一对{}来进行定义,集合中 ...

  2. bellman-ford 单源最短路问题 图解

    ​ 核心思想:松弛操作 对于边(u,v),用dist(u)和(u,v)的和尝试更新dist(v): dist(v) = min(dist(v) , dist(u)+l(u,v) 注:dist(i)为源 ...

  3. vmware安装或卸载时,显示无法打开注册表项

    ​ vmware卸载是出了名的臭名昭著,因为太难删干净了,删不干净又会有各种各样的问题.比如下文这个"无法打开注册表项" 这个我相信有很多人在重装vmware的时候遇到过,因此我来 ...

  4. sa-token client登录逻辑

  5. 实体linux服务器-由自动ip改为固定ip后,无法上网问题--配置问题解法

    新入公司,研发产业为零,开始搞. linux之前是自动获取ip地址的,网上搜索的帖子,耍流氓的居多,不能上网的原因很多,我这个是配置不对,看是否与你的一样. 1.首先看下当前电脑网卡,根据地址可以判断 ...

  6. .NET性能优化-使用结构体替代类

    前言 我们知道在C#和Java明显的一个区别就是C#可以自定义值类型,也就是今天的主角struct,我们有了更加方便的class为什么微软还加入了struct呢?这其实就是今天要谈到的一个优化性能的T ...

  7. Springboot启动类及注解说明

    Spring boot的启动是基于main方法的,其主要注解为: 1. @springBootApplication:项目的启动注解,是一个组合注解,包含@SpringbootConfiguratio ...

  8. 从URL输入到页面展现到底发生什么?DNS 解析&TCP 连接

    DNS 解析:将域名解析成 IP 地址 TCP 连接:TCP 三次握手 发送 HTTP 请求 服务器处理请求并返回 HTTP 报文 浏览器解析渲染页面 断开连接:TCP 四次挥手 一.什么是URL? ...

  9. CoaXPress 时间戳 Time Stamping

    背景 在CXP2.0之前,CXP没有定义Time Stamping时间戳的概念,但是用户对Time Stamping是有实际需求的,比如我们要对比多台设备拍摄同一个物体不同角度的照片,或者记录触发完成 ...

  10. 第24章 Java 数据类型转换

    每日一句 井底点灯深烛伊,共郎长行莫围棋. 每日一句 What we call "failure" is not falling down, but the staying dow ...