Description

在 生物课中我们学过,碱基组成了DNA(脱氧核糖核酸),他们分别可以用大写字母A,C,T,G表示,其中A总与T配对,C总与G配对。两个碱基序列能相互 匹配,当且仅当它们等长,并且任意相同位置的碱基都是能相互配对的。例如ACGTC能且仅能与TGCAG配对。一个相对短的碱基序列能通过往该序列中任意 位置补足碱基来与一个相对长的碱基序列配对。补全碱基的位置、数量不同,都将视为不同的补全方案。现在有两串碱基序列S和T,分别有n和m个碱基 (n>=m),问一共有多少种补全方案。
 

Input

数据包括三行。
第一行有两个整数n,m,表示碱基序列的长度。
第二行包含n个字符,表示碱基序列S。
第三行包含m个字符,表示碱基序列T。
两个碱基序列的字符种类只有A,C,G,T这4个大写字母。
 

Output

 
答案只包含一行,表示补全方案的个数。

Sample Input

10 3
CTAGTAGAAG
TCC

Sample Output

4

HINT

样例解释:

TCC的4种补全方案(括号中字符为补全的碱基)

(GA)TC(AT)C(TTC)

(GA)TC(ATCTT)C

(GA)T(CAT)C(TT)C

(GATCA)TC(TT)C

数据范围:

30%数据n<=1000,m<=2

50%数据n<=1000,m<=4

100%数据n<=2000,m<=n

正解:DP+高精度

解题报告:

  好久没写题了,感觉只要不是考试就写不动题了。。。

  这道题其实挺水的,就是一个编辑距离。考虑f[i][j]表示长串匹配到i,短串匹配到j的方案数,显然对于长串而言,我们需要在短串的对应位置补一些新的数字才行。所以f[i][j]=f[i-1][j]表示i这一位上与之相对应的短串上填一个新的数字,并且如果a[i]与b[j]能匹配,那么f[i][j]+=f[i-1][j-1];表示各匹配一位。

  因为答案很大,所以要写高精度。还要滚动数组。

 //It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXN = ;
const int MOD = ;
int n,m;
int match[],a[MAXN],b[MAXN];
//int f[MAXN][MAXN][10];//f[i][j]表示长串匹配到i,短串匹配到j的方案数,滚动数组
//int cnt[MAXN][MAXN];
int cnt[MAXN];
int f[MAXN][]; inline int getint()
{
int w=,q=;
char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar();
if (c=='-') q=, c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar();
return q ? -w : w;
}
/*
inline void add(int x,int y,int i,int j){
int now=1;
if(cnt[x][y]<cnt[i][j]) cnt[x][y]=cnt[i][j];
while(now<=cnt[x][y]) {
f[x][y][now]+=f[i][j][now]; now++;
}
for(int i=1;i<=cnt[x][y];i++)
if(f[x][y][i]>=MOD)
f[x][y][i+1]+=f[x][y][i]/MOD,f[x][y][i]%=MOD;
while(f[x][y][cnt[x][y]+1]) cnt[x][y]++;
}*/ inline void work(){
n=getint(); m=getint(); char c;
match[]=; match[]=; match[]=; match[]=;
for(int i=;i<=n;i++) {
c=getchar();
while(c<'A' || c>'T') c=getchar();
if(c=='A') a[i]=; else if(c=='C') a[i]=; else if(c=='T') a[i]=; else a[i]=;
}
for(int i=;i<=m;i++) {
c=getchar();
while(c<'A' || c>'T') c=getchar();
if(c=='A') b[i]=; else if(c=='C') b[i]=; else if(c=='T') b[i]=; else b[i]=;
} f[][]=; cnt[]=;
for(int i=;i<=m;i++) cnt[i]=;
for(int i=;i<=n;i++)
for(int j=m;j>=;j--) {
if(match[a[i]]!=b[j]) continue;
if(cnt[j]<cnt[j-]) cnt[j]=cnt[j-];
for(int l=;l<=cnt[j];l++) {
f[j][l]+=f[j-][l];
if(f[j][l]>=MOD) f[j][l+]+=f[j][l]/MOD,f[j][l]%=MOD;
}
while(f[j][cnt[j]+]) cnt[j]++;
}
printf("%d",f[m][cnt[m]]);
for(int i=cnt[m]-;i>=;i--) printf("%08d",f[m][i]);
/*
for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) cnt[i][j]=1;
for(int i=0;i<=n;i++) f[i][0][1]=1;
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--) {
if(cnt[i][j]<cnt[i-1][j])cnt[i][j]=cnt[i-1][j];
for(int l=1;l<=cnt[i-1][j];l++) f[i][j][l]=f[i-1][j][l]; //一位新添加一个数
if(match[a[i]]==b[j]){
add(i,j,i-1,j-1);//由上一位转移过来
}
}
printf("%d",f[n][m][cnt[n][m]]);
for(int i=cnt[n][m]-1;i>=1;i--) printf("%08d",f[n][m][i]);*/
} int main()
{
work();
return ;
}

BZOJ2764 [JLOI2011]基因补全的更多相关文章

  1. 2764: [JLOI2011]基因补全

    2764: [JLOI2011]基因补全 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 570  Solved: 187[Submit][Status ...

  2. [JLOI2011]基因补全

    1973: [JLOI2011]基因补全 Time Limit: 1 Sec  Memory Limit: 256 MB Description 在生物课中我们学过,碱基组成了DNA(脱氧核糖核酸), ...

  3. BZOJ_2764_[JLOI2011]基因补全_DP_高精度

    BZOJ_2764_[JLOI2011]基因补全_DP_高精度 Description 在生物课中我们学过,碱基组成了DNA(脱氧核糖核酸),他们分别可以用大写字母A,C,T,G表示,其中A总与T配对 ...

  4. 【bzoj2764】[JLOI2011]基因补全 dp+高精度

    题目描述 在生物课中我们学过,碱基组成了DNA(脱氧核糖核酸),他们分别可以用大写字母A,C,T,G表示,其中A总与T配对,C总与G配对.两个碱基序列能相互匹配,当且仅当它们等长,并且任意相同位置的碱 ...

  5. bzoj2764 基因补全

    Description 在生物课中我们学过,碱基组成了DNA(脱氧核糖核酸),他们分别可以用大写字母A,C,T,G表示,其中A总与T配对,C总与G配对.两个碱基序列能相互匹配,当且仅当它们等长,并且任 ...

  6. Oracle补全日志(Supplemental logging)

    Oracle补全日志(Supplemental logging)特性因其作用的不同可分为以下几种:最小(Minimal),支持所有字段(all),支持主键(primary key),支持唯一键(uni ...

  7. python 添加tab补全

    在平时查看Python方法用到tab补全还是很方便的. 1. mac 平台 配置如下: mac是类Unix平台,需要在添加一条配置内容到bash_profile 中(默认是没有这个文件,可以新建一个放 ...

  8. 记录一次bug解决过程:else未补全导致数据泄露和代码优化

    一.总结 快捷键ctrl + alt + 四个方向键 --> 倒置屏幕 未补全else逻辑,倒置查询数据泄露 空指针是最容易犯的错误,数据的空指针,可以普遍采用三目运算符来解决 SVN冲突解决关 ...

  9. jQuery 邮箱下拉列表自动补全

    综述 我想大家一定见到过,在某个网站填写邮箱的时候,还没有填写完,就会出现一系列下拉列表,帮你自动补全邮箱的功能.现在我们就用jQuery来实现一下. 博主原创代码,如有代码写的不完善的地方还望大家多 ...

随机推荐

  1. JavaScript Array 对象(length)方法 (contact、push,pop,join,map、reverse、slice、sort)

    一.Array对象属性 1.length 设置或返回数组中元素的数目. 数组的 length 属性总是比数组中定义的最后一个元素的下标大 1.对于那些具有连续元素,而且以元素 0 开始的常规数组而言, ...

  2. standard pbr(二)

    下一步看像素着色器代码 half4 fragBase (VertexOutputForwardBase i) : SV_Target { return fragForwardBaseInternal( ...

  3. Bridge Method

    1.java编译器采用Bridge Method 来兼容本该使用泛型的地方使用了非泛型的问题. public class TestBridgeMethod { public static void m ...

  4. Linux中vim命令出现E325错误解决方法

    出现该问题的原因是: vim在编辑文件的时候会创建一个swp file来保证文件的安全性,如果没有正常退出vim的,下次打开这个文件就会报E325的错误,提示swp文件已经存在. 解决方法也简单:把这 ...

  5. 023-Spring Boot 服务的注册和发现

    一.概述 服务调用 1.1.nginx方式 1.2.注册中心 二.注册中心[zookeeper] 2.1.安装zookeeper3.4.11 2.2.服务提供方,需要在服务启动时吗.,把服务的信息(I ...

  6. 001-Spring在代码中获取bean的几种方式

    一.概述 方法一:在初始化时保存ApplicationContext对象 方法二:通过Spring提供的utils类获取ApplicationContext对象 方法三:继承自抽象类Applicati ...

  7. java ReentrantLock可重入锁的使用场景

    摘要 从使用场景的角度出发来介绍对ReentrantLock的使用,相对来说容易理解一些. 场景1:如果发现该操作已经在执行中则不再执行(有状态执行) a.用在定时任务时,如果任务执行时间可能超过下次 ...

  8. 剑指offer面试54题

    面试54题: 题目:二叉搜索树的第K大节点 题:给定一颗二叉搜索树,请找出其中的第k小的结点.例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4. 解题思 ...

  9. 剑指offer 面试55题

    面试55题: 题目:二叉树的深度 题:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 解题思路: ①如果一棵树只有一个节点,它 ...

  10. 【整理学习Hadoop】Hadoop学习基础之二:分布式

      分布式系统就是将系统的应用层,数据层或其它部分构架成分布(物理和逻辑上的都可以)状(通常是网状).分布式系统通常是为了增强系统的可扩展性.稳定性和执行效率.比如在线游戏通常就是分布系统,里面所谓的 ...