1973: [JLOI2011]基因补全

Time Limit: 1 Sec  Memory Limit: 256 MB

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

这道题需要用到高精度,在高精度的同时做LCS,记得要用滚动数组,否则有可能MLE

 #include<stdio.h>
char a[],b[];
int n_a[],n_b[];
int f[][];
int how_many[][][];
int n,m;
int max(int a,int b)
{
if(a>b)
return a;
return b;
}
int min(int a,int b)
{
if(a<b)
return a;
return b;
}
void add(int a,int b,int c,int d)
{
int tmp=max(how_many[c][d][],how_many[a][b][]);
int middle=;
int middle2;
for(int i=;i<=tmp;i++)
{
middle2=(how_many[c][d][i]+how_many[a][b][i]+middle)/;
how_many[a][b][i]=(how_many[c][d][i]+how_many[a][b][i]+middle)%;
middle=middle2;
}
how_many[a][b][]=tmp;
while(middle)
{
how_many[a][b][++how_many[a][b][]]=middle%;
middle/=;
}
}/*高精度求和*/
int main()
{
scanf("%d%d",&n,&m);
scanf("%s",a);
scanf("%s",b);
for(int i=;i<n;i++)
{
if(a[i]=='A')
{
n_a[i+]=;
}
else if(a[i]=='T')
{
n_a[i+]=;
}
else if(a[i]=='G')
{
n_a[i+]=;
}
else if(a[i]=='C')
{
n_a[i+]=;
}
how_many[i%][][]=;
how_many[i%][][]=;
}/*将a字符的字母转换成可以匹配的形式,方便进行LCS*/
for(int i=;i<m;i++)
{
if(b[i]=='A')
{
n_b[i+]=;
}
else if(b[i]=='T')
{
n_b[i+]=;
}
else if(b[i]=='G')
{
n_b[i+]=;
}
else if(b[i]=='C')
{
n_b[i+]=;
}
how_many[][i][]=;
how_many[][i][]=;
}
how_many[][][]=;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
for(int k=how_many[i%][j][];k>=;k--)
how_many[i%][j][k]=;
if(n_a[i]==n_b[j])
{
if(f[i-][j-]+>=f[i-][j]&&f[i-][j-]+>=f[i][j-])
{
f[i][j]=f[i-][j-]+;
}
else if(f[i-][j-]+<=f[i-][j]&&f[i-][j]>=f[i][j-])
{
f[i][j]=f[i-][j];
}
else if(f[i][j-]>=f[i-][j]&&f[i-][j-]+<=f[i][j-])
{
f[i][j]=f[i][j-];
}
if(f[i][j]==f[i-][j-]+)
{
add(i%,j,(i-)%,j-);
}
if(f[i][j]==f[i-][j])
{
add(i%,j,(i-)%,j);
}
if(f[i][j]==f[i][j-])
{
add(i%,j,i%,j-);
}
}
else
{
if(f[i-][j]>=f[i][j-])
{
f[i][j]=f[i-][j];
}
else if(f[i][j-]>=f[i-][j])
{
f[i][j]=f[i][j-];
}
if(f[i][j]==f[i-][j])
{
add(i%,j,(i-)%,j);
}
if(f[i][j]==f[i][j-])
{
add(i%,j,i%,j-);
}
}
}
}/*LCS加上求方案数*/
for(int i=how_many[n%][m][];i;i--)
{
if(i!=how_many[n%][m][])
printf("%09d",how_many[n%][m][i]);
else
printf("%d",how_many[n%][m][i]);
}/*高精度输出*/
}

最新文章

  1. sys,os,模块-正则表达式
  2. hadoop:将WordCount打包成独立运行的jar包
  3. paip. uapi 过滤器的java php python 实现aop filter
  4. 手机 无法转移到SD卡 Andriod 导出应用程序
  5. ACM题目————字串数
  6. js笔记---封装一般运动
  7. 每天学点管理学知识——情绪ABC理论
  8. What is NetApp&#39;s Cluster File System?
  9. MFC、C++ 、Windows编程高手
  10. Vue.js 运行环境搭建详解(基于windows的手把手安装教学)及vue、node基础知识普及
  11. ContentProvider工作过程
  12. python 中range函数的用法
  13. Vue系列之 =&gt; 组件切换
  14. MAC/Xcode简单操作命令
  15. .net core 与ELK(2)安装Elasticsearch可视化工具
  16. WinRT IO相关整理
  17. 以local模式使用Xshell+Xmanager远程监控jvisualvm
  18. 【手势识别】简介 GestureDetector ScaleGestureDetector
  19. 利用VBA宏批量解决Word中图片大小、居中设置
  20. throws 与 throw

热门文章

  1. 通用后台管理系统UI-AdminLTE:构造动态菜单栏
  2. UWP 手绘视频创作工具技术分享系列 - 全新的 UWP 来画视频
  3. 【读书笔记】【深入理解ES6】#11-Promise与异步编程
  4. 在ASP.NET Core 2.0中使用CookieAuthentication
  5. ARM非对齐操作异常解决过程
  6. python基础的输入字符串的格式化
  7. H5+Ajax+WebApi实现文件下载(进度条,多文件)
  8. cs231n spring 2017 lecture4 Introduction to Neural Networks 听课笔记
  9. string::npos的一些说明
  10. [国嵌攻略][109][Linux系统调用]