大概作了一周,终于A了

类似于求最长公共子序列,稍有变形

当前序列 ch1 中字符为 a,序列 ch2 中字符为 b

则有 3 种配对方式:

1. a 与 b

2. a 与 -

3. - 与 b

动态转移方程:

dp[i][j] = max(dp[i - 1][j - 1] + g(ch1[i],ch2[j]) , dp[i - 1][j] + g(ch1[i],‘-') , dp[i][j-1] + g('-',ch2[j]))

代码如下:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[205][205];
int g(char a,char b)
{
    if( a == b ) return 5;
    if(a == 'A' && b == 'C' || b == 'A' && a == 'C') return -1;
    if(a == 'A' && b == 'G' || b == 'A' && a == 'G') return -2;
    if(a == 'A' && b == 'T' || b == 'A' && a == 'T') return -1;
    if(a == 'C' && b == 'G' || b == 'C' && a == 'G') return -3;
    if(a == 'C' && b == 'T' || b == 'C' && a == 'T') return -2;
    if(a == 'G' && b == 'T' || b == 'G' && a == 'T') return -2;
    if(a == 'A' && b == '-' || b == 'A' && a == '-') return -3;
    if(a == 'C' && b == '-' || b == 'C' && a == '-') return -4;
    if(a == 'G' && b == '-' || b == 'G' && a == '-') return -2;
    if(a == 'T' && b == '-' || b == 'T' && a == '-') return -1;
}
int main()
{
    char ch1[105],ch2[105];
    int t,s1,s2;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d %s",&s1,ch1 + 1);
        scanf("%d %s",&s2,ch2 + 1);
        for(int i = 1 ; i <= s1 ; i ++)
            dp[i][0] = dp[i - 1][0] + g('-',ch1[i]);
        for(int i = 1 ; i <= s2 ; i ++)
            dp[0][i] = dp[0][i - 1] + g(ch2[i],'-');
        for(int i = 1 ; i <= s1 ; i ++)
            for(int j = 1 ; j <=s2 ; j ++)
                dp[i][j] = max(dp[i-1][j-1] + g(ch1[i],ch2[j]),
                               max(dp[i-1][j] + g(ch1[i],'-'),dp[i][j - 1] + g('-',ch2[j])));
        printf("%d\n",dp[s1][s2]);
    }
    return 0;
}
View Code

 

posted on 2014-05-05 09:40  Acmer_侯贺帅  阅读(246)  评论(0编辑  收藏  举报