[APIO2008]DNA 题解
首先呢,看到 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\) 的方案数。
那么可以得到
\]
这个也很好理解吧。
就是说我从后向前转移,枚举后一位的优先级 \(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 题解的更多相关文章
- 4606: [Apio2008]DNA
4606: [Apio2008]DNA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 63 Solved: 36[Submit][Status][D ...
- 【BZOJ4606】[Apio2008]DNA DP
[BZOJ4606][Apio2008]DNA Description 分析如DNA序列这样的生命科学数据是计算机的一个有趣应用.从生物学的角度上说,DNA 是一种由腺嘌呤.胞嘧啶.鸟嘌呤和胸腺嘧啶这 ...
- 洛谷3763:[TJOI2017]DNA——题解
https://www.luogu.org/problemnew/show/P3763 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是 ...
- bzoj 4606: [Apio2008]DNA【dp】
写题五分钟读题两小时系列-- 看懂题的话不算难,然而我去看了大佬的blog才看懂题-- 题目大意是:一个原字符串,其中有一种通配符,合法串的定义是这个串(不含通配符))可以匹配原串并且这个串最多分成k ...
- [APIO2008]DNA
https://zybuluo.com/ysner/note/1158123 题面 戳我 解析 我们要求出第\(r\)种方案,莫过于看其前面什么时候有\(r-1\)种方案. 于是,我们要求出每种情况的 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- HDU1560 DNA sequence(IDA*)题解
DNA sequence Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- 题解【loj537】「LibreOJ NOIP Round #1」DNA 序列
题目描述 \(NOIP\)复赛之前\(HSD\)桑进行了一项研究,发现人某条染色体上的一段\(DNA\)序列中连续的\(k\)个碱基组成的碱基序列与做题的 \(AC\) 率有关!于是他想研究一下这种关 ...
- Leetcode:Repeated DNA Sequences详细题解
题目 All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: " ...
随机推荐
- python基础-基本数据类型(三)
一.散列类型 散列类型用来表示无序的集合类型 1.集合(set) Python中的集合与数学符号中的集合类似,都是用来表示无序不重复元素的集合. 1.1 集合的定义 集合使用一对{}来进行定义,集合中 ...
- bellman-ford 单源最短路问题 图解
核心思想:松弛操作 对于边(u,v),用dist(u)和(u,v)的和尝试更新dist(v): dist(v) = min(dist(v) , dist(u)+l(u,v) 注:dist(i)为源 ...
- vmware安装或卸载时,显示无法打开注册表项
vmware卸载是出了名的臭名昭著,因为太难删干净了,删不干净又会有各种各样的问题.比如下文这个"无法打开注册表项" 这个我相信有很多人在重装vmware的时候遇到过,因此我来 ...
- sa-token client登录逻辑
- 实体linux服务器-由自动ip改为固定ip后,无法上网问题--配置问题解法
新入公司,研发产业为零,开始搞. linux之前是自动获取ip地址的,网上搜索的帖子,耍流氓的居多,不能上网的原因很多,我这个是配置不对,看是否与你的一样. 1.首先看下当前电脑网卡,根据地址可以判断 ...
- .NET性能优化-使用结构体替代类
前言 我们知道在C#和Java明显的一个区别就是C#可以自定义值类型,也就是今天的主角struct,我们有了更加方便的class为什么微软还加入了struct呢?这其实就是今天要谈到的一个优化性能的T ...
- Springboot启动类及注解说明
Spring boot的启动是基于main方法的,其主要注解为: 1. @springBootApplication:项目的启动注解,是一个组合注解,包含@SpringbootConfiguratio ...
- 从URL输入到页面展现到底发生什么?DNS 解析&TCP 连接
DNS 解析:将域名解析成 IP 地址 TCP 连接:TCP 三次握手 发送 HTTP 请求 服务器处理请求并返回 HTTP 报文 浏览器解析渲染页面 断开连接:TCP 四次挥手 一.什么是URL? ...
- CoaXPress 时间戳 Time Stamping
背景 在CXP2.0之前,CXP没有定义Time Stamping时间戳的概念,但是用户对Time Stamping是有实际需求的,比如我们要对比多台设备拍摄同一个物体不同角度的照片,或者记录触发完成 ...
- 第24章 Java 数据类型转换
每日一句 井底点灯深烛伊,共郎长行莫围棋. 每日一句 What we call "failure" is not falling down, but the staying dow ...