隐藏页面特效

4606: [Apio2008]DNA

4606: [Apio2008]DNA

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 63  Solved: 36
[Submit][Status][Discuss]

Description

分析如DNA序列这样的生命科学数据是计算机的一个有趣应用。从生物学的角度上说,DNA 是一种由腺嘌呤、胞嘧啶
、鸟嘌呤和胸腺嘧啶这四种核苷酸组成的链式结构。这四种核苷酸分别用大写字母A、C、G、T表示。这样,一条DNA
单链可以被表示为一个只含以上四种字符的字符串。我们将这样的字符串称作一个DNA序列 。有时生物学家可能无
法确定一条DNA单链中的某些核苷酸。在这种情况下,字符N将被用来表示一个不确定的核苷酸。换句话说,N可以用
来表示A、C、G、T中的任何一个字符。我们称包含一个或者多个N的DNA序列为未完成序列;反之,就称作完成序列。
如果一个完成序列可以通过将一个未完成序列中的每个N任意替换成A、C、G、T得到的话,就称完成序列适合这个未
完成序列。举例来说,ACCCT适合ACNNT,但是AGGAT不适合。研究者们经常按照如下方式排序四种核苷酸:A优先于C,C
优先于G,G优先于T。如果一个DNA序列中的每个核苷酸都与其右边的相同或者优先,就将其归类为范式-1。举例来说
,AACCGT是范式-1,但是AACGTC不是。一般来说,一个DNA序列属于范式-j(j>1),只要它属于范式-(j-1)或者是一个范
式-(j-1)和一个范式-1的连接。举例来说,AACCC、ACACC和ACACA都是范式-3,但GCACAC和ACACACA不是。同样,研究
者们按照字典序对 DNA 序列进行排序。按照这个定义,最小的属于范式-3的DNA序列是AAAAA,最大的是TTTTT。这里
是另外一个例子,考虑未完成序列 ACANNCNNG。那么前7个适合这个未完成序列的DNA序列是:
ACAAACAAG
ACAAACACG
ACAAACAGG
ACAAACCAG
ACAAACCCG
ACAAACCGG
ACAAACCTG
写一个程序,找到按字典序的第R个适合给定的长度为M的未完成序列的范式-K。

 

Input

输入第一行包含三个由空格隔开的整数:M(1≤M≤50,000),K(1≤K≤10)和R(1≤R≤2×10^12)。
第二行包含一个长度为M的字符串,表示未完成序列。
保证适合该未完成序列的范式-K的总数不超过4×10^18 
因此该数可以用C和C++中的long long类型或者Pascal中的Int64类型表示。
同时,R不会超过适合给定未完成序列的范式-K的总数。

 

Output

在第一行中输出第R个适合输入中的未完成序列的范式-K。

 

Sample Input

9 3 5
ACANNCNNG

Sample Output

ACAAACCCG

HINT

 

Source

题意:

给定一个长度为m的由ACGTN组成的字符串,定义大小关系A<C<G<T,你要把其中的N替换成ACGT的其中一个,满足最多有k个不下降的子序列的同时,求出第R大的字符串。

M50000 R1012 K10

题解:

明显的计数类DP

用f[i][j][k]表示第i到n位第i位是j,这部分分了k段的个数.

这个容易转移,然后我们就一步步走呗。

f[i][j][k]=∑(f[i+1,l,k或k-1]){k或k-1视j与l的关系而定,如果j>l则为k-1,否则为k}。

复杂度 O(16MK)

#include<cstdio> using namespace std; typedef long long ll; const int N=5e4+5; int n,m,a[N];ll now; ll f[N][5][11]; ll s[N][5][11]; char str[N],path[6]={0,'A','C','G','T'}; int main(){ scanf("%d%d%lld",&n,&m,&now);//M K R scanf("%s",str+1); for(int i=1;i<=n;i++){ if(str[i]!='N'){ a[i]=str[i]=='A'?1: str[i]=='C'?2: str[i]=='G'?3:4; } } if(a[n]) f[n][a[n]][1]=1; else for(int i=1;i<=4;i++) f[n][i][1]=1; for(int i=n-1;i;i--){ for(int j=1;j<=4;j++){ if(!a[i]||a[i]==j){ for(int k=1;k<=m;k++){ for(int l=1;l<=4;l++){ f[i][j][k]+=f[i+1][l][k-(l<j)]; } } } } } for(int i=1;i<=n;i++){ for(int j=1;j<=4;j++){ for(int k=1;k<=m;k++){ s[i][j][k]=s[i][j][k-1]+f[i][j][k]; } } } for(int i=1,j,k=0;i<=n;i++){ if(a[i]){ putchar(path[a[i]]); if(k>a[i]) m--; k=a[i]; } else{ for(j=1;j<=4&&s[i][j][m-(k>j)]<now;j++) now-=s[i][j][m-(k>j)]; putchar(path[j]); if(k>j) m--; k=j; } } return 0; }

 

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/6753329.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(536)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示