POJ 1080 DP

顺便 精简了一下代码。。
题意: 给你几对儿基因序列 你可以在一个序列中插入空格,使匹配度(题中表里一一对应的分数加起来)达到最佳。
原题请戳这里

思路:
呃呃看见这道题就知道是个DP。就是转移方程怎么写呢。
mars_ch说是跟最长公共子序列有关系。(poj1458
(呃呃其实她的代码里有两句废话 就像我的第一版似的)
想了想 得出了个状态转移方程:f[i][j]=max(f[i-1][j-1]+num[a[i]][b[j]],f[i][j-1]+num[5][b[j]],f[i-1][j]+num[a[i]][5]) num数组就是题设中给的那个表。
为什么只是A了样例。
大写的不爽。
跟今天的数学作业一样。
改吧改吧还是WA。。
看了看mars_ch的题解 才知道 哦!要初始化。
一开始要进行 f[i][0]=f[i-1][0]+num[a[i]][5]; 这步操作。
万一你要在一段基因的开头直接加空格呢
是吧。
随后 就AC了。

之后 开始 精简代码。
第一版:

//By: Sirius_Ren
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cases,f[105][105],n,m;
char a[105],b[105],num[10][10];
int ch(char q){if(q=='A')return 1;if(q=='C')return 2;if(q=='G')return 3;if(q=='T')return 4;return 5;}
int main()
{
    for(int i=1;i<=4;i++)num[i][i]=5;
    num[1][2]=num[2][1]=num[1][4]=num[4][1]=num[4][5]=num[5][4]=-1;
    num[1][3]=num[3][1]=num[2][4]=num[4][2]=num[3][5]=num[5][3]=num[3][4]=num[4][3]=-2;
    num[2][3]=num[3][2]=num[1][5]=num[5][1]=-3;num[2][5]=num[5][2]=-4;
    scanf("%d",&cases);
    while(cases--){
        memset(f,0,sizeof(f));
        scanf("%d%s%d%s",&n,a+1,&m,b+1);
        for(int i=1;i<=n;i++)a[i]=ch(a[i]);
        for(int i=1;i<=m;i++)b[i]=ch(b[i]);
        for(int i=1;i<=n;i++)f[i][0]=f[i-1][0]+num[a[i]][5];
        for(int i=1;i<=m;i++)f[0][i]=f[0][i-1]+num[5][b[i]];
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(a[i]==b[j])f[i][j]=f[i-1][j-1]+5;
                else f[i][j]=max(f[i-1][j-1]+num[a[i]][b[j]],max(f[i][j-1]+num[5][b[j]],f[i-1][j]+num[a[i]][5]));
        printf("%d\n",f[n][m]);
    }
}

省略中间经过了的两三版。。。
结论:
好像不加using namespace std;这句话 以后用C++就AC不了了,用G++还能A。
终极版:

#include <cstdio>
int cases,f[105][105];
int max(int a,int b,int c){int k=(a>b?a:b);return k>c?k:c;}
char n,m,a[105],b[105],num[6][6]={{},{0,5,-1,-2,-1,-3},{0,-1,5,-3,-2,-4},{0,-2,-3,5,-2,-2},{0,-1,-2,-2,5,-1},{0,-3,-4,-2,-1}};
int ch(char q){if(q=='A')return 1;if(q=='C')return 2;if(q=='G')return 3;return 4;}
int main(){
    scanf("%d",&cases);
    while(cases--){
        scanf("%d%s%d%s",&n,a+1,&m,b+1);
        for(int i=1;i<=n;i++)a[i]=ch(a[i]);
        for(int i=1;i<=m;i++)b[i]=ch(b[i]);
        for(int i=1;i<=n;i++)f[i][0]=f[i-1][0]+num[a[i]][5];
        for(int i=1;i<=m;i++)f[0][i]=f[0][i-1]+num[5][b[i]];
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                f[i][j]=max(f[i-1][j-1]+num[a[i]][b[j]],f[i][j-1]+num[5][b[j]],f[i-1][j]+num[a[i]][5]);
        printf("%d\n",f[n][m]);
    }
}

这里写图片描述

posted @ 2016-05-13 00:22  SiriusRen  阅读(141)  评论(0编辑  收藏  举报