POJ 1080 Human Gene Functions(求两字符串相似度:LCS变形)

来源:互联网 发布:自动化软件 编辑:程序博客网 时间:2024/05/24 01:38

POJ 1080 Human Gene Functions(求两字符串相似度:LCS变形)

http://poj.org/problem?id=1080

题意: HDU1080

       给你两个由字符A,C,G,T构造的字符串s1和s2, 现在你可以在这两个字符串中插入空格, 使得两串长相等(但是不能使得s1的空格对应s2的空格位置). 然后给你s1的特定字符对应s2中特定字符所能获得的分数矩阵:

       问你最后两个字符串所能获得的最大分数是多少?

分析:

       本题很类似于求字符串最短编辑距离或者求字符串LCS的问题, 都是从两个字符串的最后一个字符入手.

       令dp[i][j]==x表示原始串s1的前i个字符和s2的前j个字符通过插入空格能获得的最大分数为x.

       初始化:dp[0][0]=0, dp[i][0]和dp[0][i]为s1和s2前i个字符对应空格的分数.

       状态转移:

       dp[i][j] = max( dp[i-1][j-1]+[s1[i]和s2[j]对应的分数] , dp[i-1][j]+[s1[i]和空格对应的分数] , dp[i][j-1]+[空格和s2[j]对应的分数] )

       上述第一个表示s1和s2最后一个位置都加空格, 所以是原本的字符对比获取分数.

       第2个表示s1的最后一个字符和s2的末尾添加空格比较获取分数.

       第3个表示s1的末尾添加空格来和s2对比.

       最终所求:dp[len(s1)][len(s2)].

AC代码:

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn=100+5;int n,m;int dp[maxn][maxn];char s1[maxn],s2[maxn];int score[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 id[500];int main(){    id['A']=0;//A字符对应0编号    id['C']=1;    id['G']=2;    id['T']=3;    id[' ']=4;    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%s",&n,s1);        scanf("%d%s",&m,s2);        //初始化        dp[0][0]=0;        for(int i=1;i<=m;i++)            dp[0][i]=dp[0][i-1]+score[id[' ']][id[s2[i-1]]];        for(int i=1;i<=n;i++)            dp[i][0]=dp[i-1][0]+score[id[' ']][id[s1[i-1]]];        //递推过程        for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)        {            int id1=id[s1[i-1]], id2=id[s2[j-1]];            dp[i][j]=dp[i-1][j-1]+score[id1][id2];            int tmp=max( dp[i-1][j]+score[id1][4] , dp[i][j-1]+score[4][id2] );            dp[i][j]=max(dp[i][j], tmp );        }        printf("%d\n",dp[n][m]);    }    return 0;}

0 0