题解 P5484 【[JLOI2011]基因补全】
我的博客
题目传送门:P5484
思路:
此题考虑直接dp,设
想想怎么转移?
我们关注A串。当A串增添一个字符
假如
假如
我们想象到方案数巨多,并且没有取模,所以肯定要用高精。
此时又有一个问题,每个状态都要开一个二维数组,还要处理高精,容易MLE,怎么办呢?
我们容易想到到
代码:(压8位高精)
#include<bits/stdc++.h>
#define lovelive 100000000
using namespace std;
int n,m,p=1,l;
char a1[2009],a2[2005];
struct aqours{
int s[105],l;
aqours(){l=1;}
}f[2][2005];
aqours operator + (aqours a,aqours b){//重载运算符
aqours c;
c.l=max(a.l,b.l);
memset(c.s,0,sizeof c.s);
for(int i=1;i<=c.l;i++){
c.s[i]+=a.s[i]+b.s[i];
if(c.s[i]>=lovelive){
c.s[i]-=lovelive;
c.s[i+1]++; //压8位高精qaq
}
}
if(c.s[c.l+1]) c.l++;
return c;
}
bool chikatakami(char a,char b){//判断是否可以匹配
return
(a=='A'&&b=='T') ||
(a=='C'&&b=='G') ||
(a=='T'&&b=='A') ||
(a=='G'&&b=='C');
}
void print(aqours a){
cout<<a.s[a.l];
for(int i=a.l-1;i;i--){
printf("%08d",a.s[i]);
}
}
int main(){
scanf("%d%d%s%s",&n,&m,a1+1,a2+1);
f[0][0].s[1]=1;f[1][0].s[1]=1;
for(int i=1;i<=n;i++,p^=1,l^=1)//滚动数组
for(int j=1;j<=m;j++){
f[p][j]=f[l][j];
if(chikatakami(a1[i],a2[j])) f[p][j]=f[p][j]+f[l][j-1];//DP
}
print(f[l][m]);
return 0;
}