https://zybuluo.com/ysner/note/1158123

题面

戳我

解析

我们要求出第\(r\)种方案,莫过于看其前面什么时候有\(r-1\)种方案。

于是,我们要求出每种情况的方案数。

设\(dp[s][m][n]\)表示第\(i-n\)个字母中,已分\(m\)段,第\(i\)个字母为s(\(s\in\{A,C,G,T\}\))字母的序号 的方案数。

状态转移方程易得:(其中\(l\)是下一个字母)

\(dp[j][k][i]+=dp[l][k-(j>l)][i+1]\)

为了下面运算方便,要对\(dp[s][m][n]\)求前缀和\(sum[s][m][n]=\sum_{i=1}^s dp[i][m][n]\)

然后就可以从前往后推了,若碰到的字母已知,看段数就可以了;

如果碰到的字母未知,枚举\(s=1...4\)的情况,如\(r>dp[s][m][n]\),说明第\(r\)个还在当前枚举字母情况的后面,继续枚举;否则,这一位就是当前枚举到的字母。

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int N=1e5+100;
char s[N];
int m,k,a[N];
ll r,n,dp[5][15][N],sum[5][15][N];
il ll gi()
{
re ll x=0,t=1;
re char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*t;
}
il void wri(re int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) wri(x/10);
putchar(x%10+'0');
}
int main()
{
n=gi();m=gi();r=gi();
scanf("%s",s+1);
fp(i,1,n)
if(s[i]=='A') a[i]=1;else if(s[i]=='C') a[i]=2;else if(s[i]=='G') a[i]=3;else if(s[i]=='T') a[i]=4;
if(a[n]) dp[a[n]][1][n]=1;
else fp(i,1,4) dp[i][1][n]=1;
fq(i,n-1,1)
fp(j,1,4)
if(!a[i]||a[i]==j)
fp(k,1,m)
fp(l,1,4)
dp[j][k][i]+=dp[l][k-(j>l)][i+1];
fp(i,1,4)
fp(j,1,n)
fp(k,1,m)
sum[i][k][j]=sum[i][k-1][j]+dp[i][k][j];
re int las=0;
fp(i,1,n)
if(a[i])
{
if(a[i]<las) --m;
las=a[i];
putchar(s[i]);
}
else
{
re int j;
for(j=1;j<=4&&r>sum[j][m-(j<las)][i];j++) r-=sum[j][m-(j<las)][i];
if(j==1) putchar('A');if(j==2) putchar('C');if(j==3) putchar('G');if(j==4) putchar('T');
if(j<las) --m;
las=j;
}
puts("");
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. [APIO2008]DNA 题解

    题目链接 首先呢,看到 A C G T 对应不同的权值,第一步就是把字母转换成数字. 我们分别对 A->1 C->2 G->3 T->4 进行标号,之后方便 \(\text{d ...

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

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

  5. bzoj AC倒序

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

  6. [LeetCode] Repeated DNA Sequences 求重复的DNA序列

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

  7. DNA解链统计物理

    来源:Kerson Huang, Lectures on Statistical Physics and Protein Folding, pp 24-25 把双链DNA解开就像拉拉链.设DNA有\( ...

  8. AC自动机+DP HDOJ 2457 DNA repair(DNA修复)

    题目链接 题意: 给n串有疾病的DNA序列,现有一串DNA序列,问最少修改几个DNA,能使新的DNA序列不含有疾病的DNA序列. 思路: 构建AC自动机,设定end结点,dp[i][j]表示长度i的前 ...

  9. [Leetcode] Repeated DNA Sequences

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

随机推荐

  1. Hive扩展功能(五)--HiveServer2服务高可用

    软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...

  2. C#——简单工厂

    简单工厂的方法实现过程核心就是之前介绍的接口应用.所以直接上代码: public interface IPerson { void Say(); } public class Student : IP ...

  3. VHDL之Serial-Parallel Multiplier

    1 Serial-parallel multiplier Figure 12.1 shows the RTL diagram of a serial-parallel multiplier. One ...

  4. 在把table表格中的数据导出到Excel的时候,以科学计数法显示位数多的数字时怎么解决?

    sbHtml.AppendFormat("<td> {0}</td>", data[i].IDcard.ToString()); sbHtml.Append ...

  5. Python 之类型转换

    # int(x[, base]) 将x转换为一个整数,base为进制,默认十进制 # # long(x[, base] ) 将x转换为一个长整数 # # float(x) 将x转换到一个浮点数 # # ...

  6. WPF在win7运行时报'Initialization of 'System.Windows.Setter' threw an exception.'

    写的一个WPF程序,在win10运行好好的,在win7就报'Initialization of 'System.Windows.Setter' threw an exception.' 原来是xaml ...

  7. H5 应用程序缓存(离线缓存)

    离线缓存这个功能的实现有以下步骤: 1,以nginx做web服务器为例,在mime.types文件中添加一行:text/cache-manifest     manifest,作用是为了让服务器识别该 ...

  8. 二叉堆 及 大根堆的python实现

    Python 二叉堆(binary heap) 二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子 ...

  9. Linux之iptables(二、基本认识和组成)

    iptables的基本认识 Netfilter组件 内核空间,集成在linux内核中 扩展各种网络服务的结构化底层框架 内核中选取五个位置放了五个hook(勾子) function(INPUT.OUT ...

  10. win10如何进入安全模式的几种方法

    首先,说一下安全模式的作用: 安全模式, 用途有很多,常见的作用有以下几点 1. 电脑可能由于安装了某些驱动或者软件,不兼容导致电脑启动不了,可以进入安全模式卸载 2. 电脑中病毒之后,可以进入安全模 ...