在生物课中我们学过,碱基组成了DNA(脱氧核糖核酸),他们分别可以用大写字母A,C,T,G表示,其中A总与T配对,C总与G配对。两个碱基序列能相互匹配,当且仅当它们等长,并且任意相同位置的碱基都是能相互配对的。例如ACGTC能且仅能与TGCAG配对。一个相对短的碱基序列能通过往该序列中任意位置补足碱基来与一个相对长的碱基序列配对。补全碱基的位置、数量不同,都将视为不同的补全方案。现在有两串碱基序列S和T,分别有n和m个碱基(n>=m),问一共有多少种补全方案。
标签:set name char s == clu for 高精度 代码 led
BZOJ_2764_[JLOI2011]基因补全_DP_高精度
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 2050 #define mod 100000000 int n,m; char s[N],w[N]; struct Big { int a[250],len; Big() {memset(a,0,sizeof(a)); len=0;} Big operator + (const Big &x) const { Big re; int l=max(len,x.len),jin=0,i; for(i=1;i<=l;i++) { int tmp=a[i]+x.a[i]+jin; jin=tmp/mod; re.a[i]=tmp%mod; } if(jin) l++; re.len=l; re.a[l]+=jin; return re; } void output() { printf("%d",a[len]); int i; for(i=len-1;i;i--) printf("%08d",a[i]); } }f[N]; bool check(int i,int j) { return (s[i]==‘T‘&&w[j]==‘A‘)||(s[i]==‘A‘&&w[j]==‘T‘)||(s[i]==‘C‘&&w[j]==‘G‘)||(s[i]==‘G‘&&w[j]==‘C‘); } int main() { scanf("%d%d%s%s",&n,&m,s+1,w+1); int i,j; f[0].len=f[0].a[1]=1; for(i=1;i<=m;i++) f[i].len=1; for(i=1;i<=n;i++) { for(j=m;j;j--) { if(check(i,j)) f[j]=f[j]+f[j-1]; } } f[m].output(); }
BZOJ_2764_[JLOI2011]基因补全_DP_高精度
标签:set name char s == clu for 高精度 代码 led
原文地址:https://www.cnblogs.com/suika/p/9062816.html