hdu 1080 dp(最长公共子序列变形)

题意:

输入俩个字符串,怎样变换使其所有字符对和最大。(字符只有'A','C','G','T','-')

其中每对字符对应的值如下:

怎样配使和最大呢。

比如:

A G T G A T G 
-  G T T A -  G 

和为 (-3)+5+5+(-2)+5+(-1) +5=14.

题解:

最长公共子序列的变形。

设dp[i][j]为a的前i个和b的前j个字符能构成的最大和。

score[][]为每对字符的值,比如score['A']['G']为'A','G'这对字符对应的值。

string a,b为输入的字符串。

 

状态转移方程:dp[i][j]从下面三种情况中 值最大的 继承

1、如果dp[i][j]=dp[i-1][j]+score[a[i-1]]['-']              //代价是 a的第i-1个字符 和 '-' 配对

2、如果dp[i][j]=dp[i][j-1]+score['-'][b[j-1]]             //代价是 '-' 和 b的第j-1个字符 配对

3、如果dp[i][j]=dp[i-1][j-1]+score[a[i-1]][b[j-1]]     //代价是 a的第i-1个字符 和 b的第j-1个字符 配对

 

注意:

初始化的时候不只是dp[0][0],还有dp[i][0],dp[0][j]。

 

AC代码:

#include <iostream>
#include <cstring>

using namespace std;

const int MAX=200;

int dp[MAX][MAX];
int score[MAX][MAX];

string a,b;
int n,m;

void init1()               //初始化
{
    score['A']['A']=5;
    score['C']['C']=5;
    score['G']['G']=5;
    score['T']['T']=5;
    score['-']['-']=-10000;
    score['A']['C']=score['C']['A']=-1;
    score['A']['G']=score['G']['A']=-2;
    score['A']['T']=score['T']['A']=-1;
    score['A']['-']=score['-']['A']=-3;
    score['C']['G']=score['G']['C']=-3;
    score['C']['T']=score['T']['C']=-2;
    score['C']['-']=score['-']['C']=-4;
    score['G']['T']=score['T']['G']=-2;
    score['G']['-']=score['-']['G']=-2;
    score['T']['-']=score['-']['T']=-1;
}

void init2()                 //dp初始化
{
    dp[0][0]=0;
    for(int k=1;k<n;k++)
        dp[k][0]=dp[k-1][0]+score[a[k-1]]['-'];

    for(int k=1;k<m;k++)
        dp[0][k]=dp[0][k-1]+score['-'][b[k-1]];
}
int mmax(int a,int b,int c)         //三个数中取最大值
{
    int p=a>b?a:b;
    p=p>c?p:c;
    return p;
}
int main()
{
    int Case;
    cin>>Case;
    while(Case--)
    {
        cin>>n>>a;
        cin>>m>>b;
        int max1,max2,max3;
        init1();
        init2();


        //dp
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                max1=dp[i-1][j-1]+score[a[i-1]][b[j-1]];
                max2=dp[i-1][j]+score[a[i-1]]['-'];
                max3=dp[i][j-1]+score['-'][b[j-1]];
                dp[i][j]=mmax(max1,max2,max3);
            }
        }

        cout<<dp[n][m]<<endl;
    }
    return 0;
}

  

posted on 2017-04-24 15:51  北溟有鱼。  阅读(157)  评论(0编辑  收藏  举报