题意:由01组成的长度为n的子串,AT由0表示,GC由1表示,求一段长度大于等于L且GC率最高的子串的起始终止坐标,若GC率相同,取长度较小,若长度相同,取起始坐标最小。

分析:

1、一个子串(i+1,j)的GC率为(sum[j] - sum[i]) / (j - i),sum[j]为前缀和

上式可以理解为点(i, sum[i])与点(j, sum[j])的斜率表达式。

因此问题可转化为求横坐标之差大于等于L的两点所组成的直线斜率的最大值。

2、https://wenku.baidu.com/view/b97cd22d0066f5335a8121a3.html?from_page=view&from_mod=download

上述论文可知,任何一个点Pt的检查集合中,不可能存在一个对最优结果有贡献的上凸点,因此我们可以删去每一个上凸点,剩下的则是一个下凸折线。

3、利用单调性求过检查点Pt与下凸折线相切的直线,从而得到当前右端点下最优的左端点。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define lowbit(x) (x & (-x))
const double eps = 1e-8;
inline int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 100000 + 10;
const int MAXT = 10000 + 10;
using namespace std;
char s[MAXN];
int sum[MAXN];
deque<int> q;
int judge(int a, int b, int c, int d){
return (sum[a] - sum[b]) * (c - d) - (sum[c] - sum[d]) * (a - b);
}
int main(){
int T;
scanf("%d", &T);
while(T--){
memset(sum, 0, sizeof sum);
q.clear();
int n, L;
scanf("%d%d", &n, &L);
scanf("%s", s + 1);
for(int i = 1; i <= n; ++i){
sum[i] = sum[i - 1] + s[i] - '0';
}
int ansl = 0, ansr = L;//最优区间初始化为(1,L)
for(int i = L; i <= n; ++i){//枚举右端点
int p = i - L;
while(q.size() > 1){//维护下凸折线
int tmpj = q[q.size() - 1];
int tmpk = q[q.size() - 2];
if(judge(tmpj, tmpk, p, tmpj) > 0){//上凸
q.pop_back();
}
else{
break;
}
}
q.push_back(p);//在右端加入新的点
while(q.size() > 1){//找与下凸折线的切点
if(judge(i, q[0], i, q[1]) <= 0){
q.pop_front();
}
else break;
}
int tmp = judge(i, q[0], ansr, ansl);
if(tmp > 0 || (tmp == 0 && i - q[0] < ansr - ansl)){
ansl = q[0];
ansr = i;
}
}
printf("%d %d\n", ansl + 1, ansr);
}
return 0;
}

  

UVA - 1451 Average (斜率优化)的更多相关文章

  1. UVa 1451 Average - 斜率优化

    A DNA sequence consists of four letters, A, C, G, and T. The GC-ratio of a DNA sequence is the numbe ...

  2. UVA 1451 Average平均值 (数形结合,斜率优化)

    摘要:数形结合,斜率优化,单调队列. 题意:求一个长度为n的01串的子串,子串长度至少为L,平均值应该尽量大,多个满足条件取长度最短,还有多个的话,取起点最靠左. 求出前缀和S[i],令点Pi表示(i ...

  3. UVA 1451 Average

    A DNA sequence consists of four letters, A, C, G, and T. The GC-ratio of a DNA sequence is the numbe ...

  4. HDU 2993 MAX Average Problem dp斜率优化

    MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. MAX Average Problem(斜率优化dp)

    MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  6. 【UVA 1451】Average

    题 题意 求长度为n的01串中1占总长(大于L)的比例最大的一个子串起点和终点. 分析 前缀和s[i]保存前i个数有几个1,[j+1,i] 这段区间1的比例就是(s[i]-s[j])/(i-j),于是 ...

  7. HDU 2993 MAX Average Problem(斜率优化DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 题目大意:给定一个长度为n(最长为10^5)的正整数序列,求出连续的最短为k的子序列平均值的最大 ...

  8. UVALive 4726 Average ——(斜率优化DP)

    这是第一次写斜率优化DP= =.具体的做法参照周源论文<浅谈数形结合思想在信息学竞赛中的应用>.这里仅提供一下AC的代码. 有两点值得注意:1.我这个队列的front和back都是闭区间的 ...

  9. 斜率优化dp(POJ1180 Uva1451)

    学这个斜率优化dp却找到这个真心容易出错的题目,其中要从n倒过来到1的确实没有想到,另外斜率优化dp的算法一开始看网上各种大牛博客自以为懂了,最后才发现是错了. 不过觉得看那些博客中都是用文字来描述, ...

随机推荐

  1. 无root开热点教程

    本教程适用于无root类开热点,理论上动态云免等均可使用 热点成功测试方法与免流测试方法相同,一般都为查看ip所在地区 热点端 1.打开个人热点 2.如果是tinyproxy可打开右上角菜单,点击热点 ...

  2. 「Luogu P3078 [USACO13MAR]扑克牌型Poker Hands」

    本题有\(O(N)\)的优秀做法,但是因为在考场上不一定能想到,就来分享一种\(O(N\log_2N)\)的做法.虽然有点慢,但是可以过. 前置芝士 线段树:提高组及以上必备内容,不会的同学可以学习一 ...

  3. SystemVerilog for design 笔记(二)

    转载请标明出处 1. System Verilog文本值和数据类型 1.1. 增强的文本值赋值 相对于verilog,SV在文本值赋值时可以1.无需指定进制    2.赋值可以是逻辑1 用法: reg ...

  4. P1120/UVA307 小木棍(sticks) 题解

    题目描述 pdf 题解 注意的问题是,各个原始木棒的长度都是一样的! 说一下本题的总思路即:DFS+超强力剪枝!(详见本人的 AC 程序) 首先,我们要从小到大枚举原始木棒的长度len,也就是枚举答案 ...

  5. R语言 sample抽样函数

    Sample 函数用法: sample(x, size, replace = FALSE, prob = NULL) Arguments x - 可以是含有一个或多个元素的向量或只是一个正整数.x的长 ...

  6. Windows一键启动多个软件

    @echo off title 启动工作环境 @echo 正在启动FileZilla%start+空格+/d+空格+目录路径+空格+程序名 % start /d"F:\安装包\FileZil ...

  7. Servlet对用户输入的数据进行读取

    逻辑代码: package com.zyb.test; import java.io.IOException; import java.util.Enumeration; import javax.s ...

  8. Py西游攻关之基础数据类型(六)-文件操作

    Py西游攻关之基础数据类型 - Yuan先生 https://www.cnblogs.com/yuanchenqi/articles/5782764.html 九 文件操作 9.1 对文件操作流程 打 ...

  9. Java程序挂掉的几种可能

    今天花了一整天在跟踪一个问题,每次感觉已经快找到原因的时候发现现象又变了,我觉得从中吸取的教训可以给大家分享一下. 为了重现这个现象,我写了一个简单的例子.在本例中,先初始化了一个map,然后用一个无 ...

  10. JS数组精简的十三个技巧

    1.删除数组的重复项 第一种方式 var fruits = ['banana', 'apple', 'orange', 'apple', 'orange', 'grape', 'watermelon' ...