zoukankan      html  css  js  c++  java
  • dp poj 1080 Human Gene Functions

    题目链接:

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

    题目大意:

    给两个由A、C、T、G四个字符组成的字符串,可以在两串中加入-,使得两串长度相等。

    每两个字符匹配时都有个值,求怎样安排使得总的值最大,两个-不能匹配。

    解题思路:

    这题转化一下就是一个裸的最长公共子串问题,只不过要求匹配时长度一样。

    dp[i][j]表示第一串的第前i个字符和第二串的前j个字符匹配时,能达到的最大值。

    初始化时注意dp[0][j]和dp[j][0]不能为零,为相应字符与-匹配时的总和。

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #define eps 1e-6
    #define INF 0x1f1f1f1f
    #define PI acos(-1.0)
    #define ll __int64
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    /*
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    */
    #define Maxn 110
    map<char,int>myp;
    int mar[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,-INF}}; //存入值表
    char sa1[Maxn],sa2[Maxn];
    int a[Maxn],b[Maxn];
    int dp[Maxn][Maxn];
    
    int main()
    {
       myp['A']=0,myp['C']=1,myp['G']=2,myp['T']=3,myp['-']=4; //将字符和表映射起来
       int t,len1,len2;
    
       scanf("%d",&t);
       while(t--)
       {
          scanf("%d%s",&len1,sa1+1);
          for(int i=1;i<=len1;i++)
             a[i]=myp[sa1[i]]; //转化成相应的代表数字
          scanf("%d%s",&len2,sa2+1);
          for(int i=1;i<=len2;i++)
             b[i]=myp[sa2[i]];
    
          memset(dp,-INF,sizeof(dp));
          dp[0][0]=0;
          for(int i=1;i<=len1;i++) //注意初始化时 是和-匹配
              dp[i][0]=dp[i-1][0]+mar[a[i]][4];
             // printf("i:%d j:%d %d
    ",i,0,dp[i][0]);
          for(int j=1;j<=len2;j++)
             dp[0][j]=dp[0][j-1]+mar[b[j]][4];
             //printf("i:%d j:%d %d
    ",0,j,dp[0][j]);
        //  putchar('
    ');
          for(int i=1;i<=len1;i++)
             for(int j=1;j<=len2;j++)
             {
                int Mx=dp[i][j];
                Mx=max(Mx,dp[i-1][j-1]+mar[a[i]][b[j]]); //i-j匹配
                Mx=max(Mx,max(dp[i-1][j]+mar[a[i]][4],dp[i][j-1]+mar[b[j]][4])); //(j和i-1,i和-)匹配 (i和j-1,-和j)匹配
                Mx=max(Mx,dp[i-1][j-1]+mar[a[i]][4]+mar[b[i]][4]); //两个都匹配-
                dp[i][j]=Mx;
                //printf("i:%d j:%d %d
    ",i,j,dp[i][j]);
             }
          printf("%d
    ",dp[len1][len2]);
       }
       return 0;
    }
    


  • 相关阅读:
    docker安装
    win8换win7的操作方法
    java数组实现队列
    springMVC源码学习之获取参数名
    SpringMVC源码学习之request处理流程
    LeetCode 231. Power of Two
    LeetCode 202. Happy Number
    LeetCode 171. Excel Sheet Column Number
    Eclipse 保存代码时,不自动换行设置
    LeetCode 141. Linked List Cycle
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3271368.html
Copyright © 2011-2022 走看看