洛谷【P1140】相似基因

浅谈\(DP\)https://www.cnblogs.com/AKMer/p/10437525.html

题目传送门:https://www.luogu.org/problemnew/show/P1140

以已经匹配完了的长度为阶段,\(f[i][j]\)为状态,表示已匹配了第一个串的\(i\)个,第二个串的前\(j\)个。

转移则是\(f[i][j]=max(f[i][j],f[i-1][j-1]+cost[a_i][b_j],f[i-1][j]+cost[a_i]['-'],f[i][j-1]+cost[b_j]['-'])\)

\(cost[s1][s2]\)表示这俩字符的匹配贡献。

时间复杂度:\(O(n^2)\)

空间复杂度:\(O(n^2)\)

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int n,m;
int p[105];
int f[105][105];
char a[105],b[105];
int cost[5][5]={
    5,-1,-2,-1,-3,
    -1,5,-3,-2,-4,
    -2,-3,5,-2,-2,
    -1,-2,-2,5,-1,
    -3,-4,-2,-1,0
};

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}

int main() {
    p['A']=0,p['C']=1,p['G']=2,p['T']=3,p['-']=4;
    n=read(),scanf("%s",a+1);
    m=read(),scanf("%s",b+1);
    memset(f,-63,sizeof(f));f[0][0]=0;
    for(int i=1;i<=n;i++)
        f[i][0]=f[i-1][0]+cost[p[(int)a[i]]][p['-']];
    for(int i=1;i<=m;i++)
        f[0][i]=f[0][i-1]+cost[p[(int)b[i]]][p['-']];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) {
            int A=a[i],B=b[j];
            f[i][j]=max(f[i][j],f[i-1][j-1]+cost[p[A]][p[B]]);
            f[i][j]=max(f[i][j],f[i-1][j]+cost[p[A]][p['-']]);
            f[i][j]=max(f[i][j],f[i][j-1]+cost[p[B]][p['-']]);
        }
    printf("%d\n",f[n][m]);
    return 0;
}
posted @ 2019-02-26 15:27  AKMer  阅读(165)  评论(0编辑  收藏  举报