• 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;
    }
    

      

    人生如修仙,岂是一日间。何时登临顶,上善若水前。
  • 相关阅读:
    某地理位置模拟APP从壳流程分析到破解
    GDB多线程调试分析
    ARM平台指令虚拟化初探
    爱加密企业版静态脱壳机编写
    APK加固之静态脱壳机编写入门
    APK加固之类抽取分析与修复
    Xposed截获 Android手机QQ密码
    菜鸟 学注册机编写之 Android app
    Pstools使用
    msf端口扫描
  • 原文地址:https://www.cnblogs.com/f-society/p/6757243.html
Copyright © 2020-2023  润新知