Description
在生物課中我們學過,鹼基組成了DNA(脫氧核糖核酸),他們分別可以用大寫字母A,C,T,G表示,其中A總與T配對,C總與G配對。兩個鹼基序列能相互匹配,當且僅當它們等長,並且任意相同位置的鹼基都是能相互配對的。例如ACGTC能且僅能與TGCAG配對。一個相對短的鹼基序列能通過往該序列中任意位置補足鹼基來與一個相對長的鹼基序列配對。補全鹼基的位置、數量不同,都將視爲不同的補全方案。現在有兩串鹼基序列S和T,分別有n和m個鹼基(n>=m),問一共有多少種補全方案。
Input
Output
答案只包含一行,表示補全方案的個數。
Sample Input
Sample Output
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方案數的題目,f[j]+=f[j-1](當a[i]==b[j]時)
注意要用高精度!!!
#include<stdio.h>
#include<string.h>
char a[2001];
char b[2001],la,lb;
int mod=1e8;
int f[2001][2001];
int cnt[2001];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
scanf("%s%s",a+1,b+1);
f[0][1]=1;
cnt[0]=1;
for(int i=0;i<=m;i++)
cnt[i]=1;
for(int i=1;i<=n;i++)
{
if(a[i]=='A')
a[i]='T';
else if(a[i]=='C')
a[i]='G';
else if(a[i]=='T')
a[i]='A';
else
a[i]='C';
}
for(int i=1;i<=n;i++)
for(int j=m;j>0;j--)
{
if(a[i]!=b[j])
continue;
if(cnt[j]<cnt[j-1])
cnt[j]=cnt[j-1];
for(int l=1;l<=cnt[j];l++)
{
f[j][l]+=f[j-1][l];
if(f[j][l]>=mod)
{
f[j][l+1]+=f[j][l]/mod;
f[j][l]%=mod;
}
}
while(f[j][cnt[j]+1])
cnt[j]++;
}
printf("%d",f[m][cnt[m]]);
for(int i=cnt[m]-1;i>0;i--)
printf("%08d",f[m][i]);
}
f數組的第二維我用一個cnt來存的,爲了求高精度.
剩下的就不難了.