zoukankan      html  css  js  c++  java
  • 【bzoj5107】[CodePlus2017]找爸爸 dp

    题目描述

    给出两个基因串,你需要在其中插入任意个空格,使得两个串长度相同。如果两个串的某同一位置都是字母则获得某给定收益,对于每个串的每个长度为k的连续空格段要付出a(k-1)+b的损失。求最大净收益。

    输入

    输入第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

    输出

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

    样例输入

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

    样例输出

    4


    题解

    dp

    显然空格匹配空格是血亏的,所以一定不会有两个位置都是空格。

    于是可以分别设 $f[i][j],g[i][j],h[i][j]$ 表示第一个串匹配到 $i$ ,第二个串匹配到 $j$ ,最后为 空格&字母/字母&空格/字母&字母 的最大收益。

    那么直接枚举 $i$ 和 $j$ 转移即可。

    注意一下边界问题。

    时间复杂度 $O(nm)$ 

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 3010
    #define val(c) (c == 'A' ? 0 : c == 'T' ? 1 : c == 'G' ? 2 : 3)
    using namespace std;
    int v[4][4] , f[N][N] , g[N][N] , h[N][N];
    char A[N] , B[N];
    int main()
    {
    	int n , m , i , j , p , q;
    	scanf("%s%s" , A + 1 , B + 1) , n = strlen(A + 1) , m = strlen(B + 1);
    	for(i = 0 ; i < 4 ; i ++ )
    		for(j = 0 ; j < 4 ; j ++ )
    			scanf("%d" , &v[i][j]);
    	scanf("%d%d" , &p , &q);
    	memset(f , 0xc0 , sizeof(f));
    	memset(g , 0xc0 , sizeof(g));
    	memset(h , 0xc0 , sizeof(h));
    	f[0][1] = g[1][0] = -p , h[0][0] = 0;
    	for(i = 2 ; i <= m ; i ++ ) f[0][i] = f[0][i - 1] - q;
    	for(i = 2 ; i <= n ; i ++ ) g[i][0] = g[i - 1][0] - q;
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		for(j = 1 ; j <= m ; j ++ )
    		{
    			f[i][j] = max(f[i][j - 1] - q , max(g[i][j - 1] , h[i][j - 1]) - p);
    			g[i][j] = max(max(f[i - 1][j] , h[i - 1][j]) - p , g[i - 1][j] - q);
    			h[i][j] = max(max(f[i - 1][j - 1] , g[i - 1][j - 1]) , h[i - 1][j - 1]) + v[val(A[i])][val(B[j])];
    		}
    	}
    	printf("%d
    " , max(max(f[n][m] , g[n][m]) , h[n][m]));
    	return 0;
    }
    

     

  • 相关阅读:
    权限设计
    ts infer关键字
    Array初始化 以及 Array.prototype.map()的一些问题
    同步、异步、事件循环
    Spring学习笔记(一)
    【面试】关于get和post两种方法的不同。
    【算法】背包问题
    当你在浏览器输入一个网址(如http://www.taobao.com),按回车之后发生了什么?
    数据库语句复习笔记
    【算法】雀魂启动(笔试题)
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7992539.html
Copyright © 2011-2022 走看看