• bzoj5107[CodePlus2017]找爸爸


     [CodePlus2017]找爸爸

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 128  Solved: 87
    [Submit][Status][Discuss]

    Description

    小A最近一直在找自己的爸爸,用什么办法呢,就是DNA比对。小A有一套自己的DNA序列比较方法,其最终目标是最
    大化两个DNA序列的相似程度,具体步骤如下:1.给出两个DNA序列,第一个长度为n,第二个长度为m。2.在两个序
    列的任意位置插入任意多的空格,使得两个字符串长度相同3.逐位进行匹配,如果两个序列相同位置上的字符都不
    是空格,假设第一个是x,第二个是y,那么他们的相似程度由d(x,y)定义。对于两个序列中任意一段极长的长度为
    k的连续空格,我们定义这段空格的相似程度为g(k)=-A-B(k-1)。那么最终两个序列的相似程度就是所有的d(x,y)
    加上所有的极长空格段的相似程度之和。现在小A通过某种奥妙重重的方式得到了小B的DNA序列中的一段,他想请
    你帮他算一下小A的DNA序列和小B的DNA序列的最大相似程度。
     

    Input

    输入第1行一个字符串,表示小A的DNA序列。
    输入第2行一个字符串,表示小B的DNA序列。
    接下来4行,每行4个整数,用空格隔开,表示d数组,
    具体顺序如下所示。
    d(A,A)d(A,T)d(A,G)d(A,C)
    d(T,A)d(T,T)d(T,G)d(T,C)
    d(G,A)d(G,T)d(G,G)d(G,C)
    d(C,A)d(C,T)d(C,G)d(C,C)
    最后一行两个用空格隔开的正整数A,B,意义如题中所述。
    对于所有测试点
    有0<B<A≤1000,-1000≤d(x,y)≤1000,d(x,y)=d(y,x),
    序列只包含{A,T,G,C}四种字符。
    N+M<=3000

    Output

    输出共一行,表示两个序列的最大相似程度
     

    Sample Input

    ATGG
    ATCC
    5 -4 -4 -4
    -4 5 -4 -4
    -4 -4 5 -4
    -4 -4 -4 5
    2 1

    Sample Output

    4
    首先,将序列补成如下形式("-"代表空格)
    ATGG--
    AT--CC
    然后所有d(x,y)的和为d(A,A)+d(T,T)=10所有极长连续空格段的相似程度之和为g(2)+g(2)=-6总和为4,可以验证
    ,这是相似程度最大的情况。

    HINT

    来自 CodePlus 2017 11 月赛,清华大学计算机科学与技术系学生算法与竞赛协会 荣誉出品。

    Credit:idea/邢健开 命题/邢健开 验题/陈宇

    Git Repo:https://git.thusaac.org/publish/CodePlus201711

    本次比赛的官方网址:cp.thusaac.org

    感谢腾讯公司对此次比赛的支持。

    Source

     题解:dp,f[i][j][k][p]表示A串到了第i位,B串到了第j位,A串最后是否为空格,B串最后是否为空格
    因为是一次函数。
     1 #include<cstring>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdio>
     6 
     7 #define inf 1000000007
     8 #define ll long long
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,f=1;char ch=getchar();
    13     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
    14     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 
    18 int n,m,d[5][5],dp[3005][3005][2][2],A,B;
    19 char s1[3005],s2[3005];
    20 
    21 inline int D(char ch)
    22 {
    23     if (ch=='A') return 1;
    24     else if (ch=='T') return 2;
    25     else if (ch=='G') return 3;
    26     else return 4;
    27 }
    28 int main()
    29 {
    30     scanf("%s%s",s1+1,s2+1);
    31     n=strlen(s1+1);m=strlen(s2+1);
    32     for (int i=1;i<=4;i++)for (int j=1;j<=4;j++) d[i][j]=read();
    33     A=read();B=read();
    34     for (int i=0;i<=n;i++)
    35         for (int j=0;j<=m;j++)
    36             for (int x1=0;x1<2;x1++)
    37                 for (int x2=0;x2<2;x2++)
    38                     dp[i][j][x1][x2]=-inf;
    39                     
    40     dp[0][0][1][1]=0;dp[1][0][1][0]=dp[0][1][0][1]=-A; 
    41     for (int i=1;i<=n;i++)
    42         for (int j=1;j<=m;j++)
    43         {
    44             int x=D(s1[i]),y=D(s2[j]);
    45             for (int x1=0;x1<2;x1++)
    46             for (int x2=0;x2<2;x2++)
    47             {
    48                 if (!x1&&!x2) continue;
    49                 dp[i][j][1][1]=max(dp[i-1][j-1][x1][x2]+d[x][y],dp[i][j][1][1]);
    50                 dp[i][j][1][0]=max(dp[i-1][j][x1][x2]-((x2)?A:B),dp[i][j][1][0]);
    51                 dp[i][j][0][1]=max(dp[i][j-1][x1][x2]-((x1)?A:B),dp[i][j][0][1]);
    52             }       
    53         }
    54         
    55     printf("%d",max(dp[n][m][1][1],max(dp[n][m][1][0],dp[n][m][0][1])));
    56 }
  • 相关阅读:
    HDU 1455 http://acm.hdu.edu.cn/showproblem.php?pid=1455
    UVA 11300 Spreading the Wealth
    HDU 1702 http://acm.hdu.edu.cn/showproblem.php?pid=1702
    栈的简单应用 HDU 1022 http://acm.hdu.edu.cn/showproblem.php?pid=1022
    HDU 1702 队列与栈的简单运用http://acm.hdu.edu.cn/showproblem.php?pid=1702
    背包模板(01背包,完全背包,多重背包)
    XSS内容拓展--伪造你的IP
    Linux文件系统
    2015阿里校招研发工程师笔试题
    鸟哥的私房菜复习一
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8119378.html
Copyright © 2020-2023  润新知