题目链接

首先呢,看到 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. 论文解读(DCRN)《Deep Graph Clustering via Dual Correlation Reduction》

    论文信息 论文标题:Deep Graph Clustering via Dual Correlation Reduction论文作者:Yue Liu, Wenxuan Tu, Sihang Zhou, ...

  2. Python 中删除列表元素的三种方法

    列表基本上是 Python 中最常用的数据结构之一了,并且删除操作也是经常使用的. 那到底有哪些方法可以删除列表中的元素呢?这篇文章就来总结一下. 一共有三种方法,分别是 remove,pop 和 d ...

  3. 数据结构_C语言_单链表

    # include <stdio.h> # include <stdbool.h> # include <malloc.h> typedef int DataTyp ...

  4. Spring Ioc源码分析系列--Ioc的基础知识准备

    Spring Ioc源码分析系列--Ioc的基础知识准备 本系列文章代码基于Spring Framework 5.2.x Ioc的概念 在Spring里,Ioc的定义为The IoC Containe ...

  5. Nginx的mirror指令能干啥?

    mirror 流量复制 Nginx的 mirror 指令来自于 ngx_http_mirror_module 模块 Nginx Version > 1.13.4 mirror 指令提供的核心功能 ...

  6. 3┃音视频直播系统之浏览器中通过 WebRTC 直播视频实时录制回放下载

    一.录制分类 在音视频会议.在线教育等系统中,录制是一个特别重要的功能 录制一般分为服务端录制和客户端录制 服务端录制:优点是不用担心客户因自身电脑问题造成录制失败(如磁盘空间不足),也不会因录制时抢 ...

  7. c# SendInput模拟输入字符和按键

    介绍: 该程序本意是为了在彩六里打中文用的,现整理出来供大家复制粘贴.(源程序已开源至GitHub - 彩六中文输入) 主要使用SendInput函数,与c语言中用法一致.(部分代码来自网络) 命名空 ...

  8. 【算法】希尔排序(Shell Sort)(四)

    希尔排序(Shell Sort) 1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版.它与插入排序的不同之处在于,它会优先比较距离较远的元素.希尔排序又叫缩小增量排序. ...

  9. linux篇-Centos7jdk安装

    2.1查看现有JDK #rpm -qa|grep jdk (如果有其他版本的JDK建议卸载) 卸载其他版本的JDK命令 #yum –y remove java-1.6.0 #yum –y remov ...

  10. 安装Tomcat到Linux(源码)

    运行环境 系统版本:CentOS Linux release 7.3.1611 软件版本:Tomcat-9.0.11 硬件要求:无 安装过程 1.安装YUM-EPEL存储库 YUM-EPEL存储库由E ...