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. 微信开发配置JSSDK,注入权限验证,以及invalid signature签名错误解决

    在微信开发中很多功能都要用到微信JSSDK,关于JSSDK的使用,微信官方的文档已经比较详细,一定要仔细去看文档. <script src="https://res.wx.qq.com ...

  2. id拼接保存到单个字段后作为表连接的查询条件

    SELECT q.id, concat(q. NAME) qname, d.id did, d. NAME FROM question_po q LEFT JOIN data_configuratio ...

  3. Redis 之仿微博demo

    一.用户注册登录 include './header.php'; include './function.php'; $username = p('username'); $password = p( ...

  4. vue 项目的I18n国际化之路

    I18n (internationalization ) ---未完善 产品国际化是产品后期维护及推广中重要的一环,通过国际化操作使得产品能更好适应不同语言和地区的需求 国际化重点:1. 语言语言本地 ...

  5. yum http源

    统一集群内,有一个yum本地源即可,集群内其他机器的yum可配成http源 方法: yum1:本地yum源节点 yum2:集群内其他节点 yum1: ①service httpd start ②mki ...

  6. Alliances

    树国是一个有n个城市的国家,城市编号为1∼n.连接这些城市的道路网络形如一棵树, 即任意两个城市之间有恰好一条路径.城市中有k个帮派,编号为1∼k.每个帮派会占据一些城市,以进行非法交易.有时帮派之间 ...

  7. [繁华模拟赛]Evensgn 剪树枝

    Evensgn 剪树枝 题目 繁华中学有一棵苹果树.苹果树有 n 个节点(也就是苹果),n − 1 条边(也就 是树枝).调皮的 Evensgn 爬到苹果树上.他发现这棵苹果树上的苹果有两种:一 种是 ...

  8. 清北学堂模拟赛d4t4 a

    分析:感觉和dp的状态转移方式有点类似,对于一个数,你不能看有多少个状态能转移到它,你要看它能转移到多少个状态,相当于刷表法和填表法的区别,对于这道题也是一样,我们不能看有多少个数是x的倍数,而是每次 ...

  9. float在内存中的存放

    一个float型实数在内存中占4个字节,即32个二进制bit,从低位到高位依次叫第0位到第31位.这32位可以分为3个部分:符号位(第31位),阶码(第30位到第23位共8位),尾数(最低23位). ...

  10. no_merge hint

    This is tested in 10gR2. SQL> select * from v$version; BANNER ----------------------------------- ...