bzoj 2764 //2764: [JLOI2011]基因补全

bzoj 2764 //2764: [JLOI2011]基因补全 //在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=2764

更多题解,详见https://blog.csdn.net/mrcrack/article/details/90228694BZOJ刷题记录

非高精度dp代码

//2764: [JLOI2011]基因补全
//在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=2764
//题目出得不错,样例有解释,至少题意能让人很明白。
//此文https://www.luogu.org/problemnew/solution/P5484  作者: AquaRio  更新时间: 2019-08-22 20:26思路很棒,摘抄如下

bzoj 2764 //2764: [JLOI2011]基因补全_第1张图片

for(i=0;i<=n;i++)f[i][0]=1;//此处初始化比较难写,查遍全网未得,只好自个模拟,还好结果不错。2019-9-24
/*
f[i][j]初始化得出如下
ABA
A
f[1][1]=1,f[3][1]=2
'A'=='A' f[1][1]=f[0][1]+f[0][0]=1,故f[0][0]=1,f[0][1]=0;
'B'!='A' f[2][1]=f[1][1]=1
'A'=='A' f[3][1]=f[2][1]+f[3][0]=2,故f[3][0]=1;
*/
//样例通过,在https://www.luogu.org/problem/P5484提交70分,测试点1,2,9WA.基本可以确认,long long溢出.
//以下为未采用高精度的dp代码,f[i][j]初始化部分,提供给读者参考,70分。2019-9-24
#include
#include
#define LL long long
#define maxn 2010
LL f[maxn][maxn];
int n,m;
char a[maxn],b[maxn];
int main(){
    int i,j;
    scanf("%d%d",&n,&m);
    scanf("%s%s",a+1,b+1);
    for(i=1;i<=n;i++)
        if(a[i]=='A')a[i]='T';
        else if(a[i]=='T')a[i]='A';
        else if(a[i]=='C')a[i]='G';
        else if(a[i]=='G')a[i]='C';
    memset(f,0,sizeof(f));
    for(i=0;i<=n;i++)f[i][0]=1;//此处初始化比较难写,查遍全网未得,只好自个模拟,还好结果不错。2019-9-24
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
            if(a[i]==b[j])f[i][j]=f[i-1][j-1]+f[i-1][j];//此处错写成if(a[i]==b[i])f[i][j]=f[i-1][j-1]+f[i-1][j];
            else f[i][j]=f[i-1][j];
    printf("%lld\n",f[n][m]);
    return 0;
}
 

高精度dp代码

836ms / 16.27MB / 854B C++

//2764: [JLOI2011]基因补全
//在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=2764
//题目出得不错,样例有解释,至少题意能让人很明白。
//此文https://www.luogu.org/problemnew/solution/P5484  作者: AquaRio  更新时间: 2019-08-22 20:26思路很棒,摘抄如下

bzoj 2764 //2764: [JLOI2011]基因补全_第2张图片

//滚动数组原理,此文https://www.luogu.org/problemnew/solution/P5484  作者: Ofnoname  更新时间: 2019-07-30 23:15介绍得不错,摘抄如下
/*

bzoj 2764 //2764: [JLOI2011]基因补全_第3张图片

*/
//样例通过,提交60分,测试点1,2,4,9WA.
//查了好久才发现,d=max(cnt[a],cnt[b]),cnt[b]=d;//此处错写成d=max(cnt[a],cnt[b]);
//提交AC.2019-9-24 21:51
#include
#include
#define maxn 2010
int f[maxn][maxn];//此处错写成int f[maxn][100];90分,测试点1WA.
int n,m,cnt[maxn];//cnt[i]是f[i][]的数据长度
char a[maxn],b[maxn];
int max(int a,int b){
    return a>b?a:b;
}
void add(int a,int b){//f[b]=f[a]+f[b]
    int i,d;
    d=max(cnt[a],cnt[b]),cnt[b]=d;//此处错写成d=max(cnt[a],cnt[b]);
    for(i=1;i<=d;i++){
        f[b][i]+=f[a][i];
        f[b][i+1]+=f[b][i]/10;
        f[b][i]%=10;
    }
    if(f[b][i])cnt[b]=i;
}
int main(){
    int i,j;
    scanf("%d%d",&n,&m);
    scanf("%s%s",a+1,b+1);
    for(i=1;i<=n;i++)
        if(a[i]=='A')a[i]='T';
        else if(a[i]=='T')a[i]='A';
        else if(a[i]=='C')a[i]='G';
        else if(a[i]=='G')a[i]='C';
    memset(f,0,sizeof(f)),f[0][1]=1;
    for(i=0;i<=m;i++)cnt[i]=1;
    for(i=1;i<=n;i++)
        for(j=m;j>=1;j--)
            if(a[i]==b[j])add(j-1,j);//f[j]=f[j-1]+f[j];
    for(i=cnt[m];i>=1;i--)printf("%d",f[m][i]);
    return 0;
}

高精度dp代码   压8位高精

bzoj 2764

2804 kb 180 ms C++/Edit 1126 B

洛谷171ms / 2.76MB / 877B C++

#include
#include
#define maxn 2010
#define mod 100000000
int f[maxn][maxn/8];
int n,m,cnt[maxn];//cnt[i]是f[i][]的数据长度
char a[maxn],b[maxn];
int max(int a,int b){
    return a>b?a:b;
}
void add(int a,int b){//f[b]=f[a]+f[b]
    int i,d;
    d=max(cnt[a],cnt[b]),cnt[b]=d;//此处错写成d=max(cnt[a],cnt[b]);
    for(i=1;i<=d;i++){
        f[b][i]+=f[a][i];
        f[b][i+1]+=f[b][i]/mod;
        f[b][i]%=mod;
    }
    if(f[b][i])cnt[b]=i;
}
int main(){
    int i,j;
    scanf("%d%d",&n,&m);
    scanf("%s%s",a+1,b+1);
    for(i=1;i<=n;i++)
        if(a[i]=='A')a[i]='T';
        else if(a[i]=='T')a[i]='A';
        else if(a[i]=='C')a[i]='G';
        else if(a[i]=='G')a[i]='C';
    memset(f,0,sizeof(f)),f[0][1]=1;
    for(i=0;i<=m;i++)cnt[i]=1;
    for(i=1;i<=n;i++)
        for(j=m;j>=1;j--)
            if(a[i]==b[j])add(j-1,j);//f[j]=f[j-1]+f[j];
    printf("%d",f[m][cnt[m]]);
    for(i=cnt[m]-1;i>=1;i--)printf("%08d",f[m][i]);
    return 0;
}

你可能感兴趣的:(跟着大佬学算法)