题目描述

JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物。萌萌的礼品店很神奇,所有出售的礼物都按照特定的顺序都排成一列,而且相邻的礼物之间有一种神秘的美感。于是,JYY决定从中挑选连续的一些礼物,但究竟选哪些呢?假设礼品店一共有N件礼物排成一列,每件礼物都有它的美观度。排在第i(1\leq i\leq N1≤i≤N)个位置的礼物美观度为正整数A_iAi​。JYY决定选出其中连续的一段,即编号为礼物i,i+1,…,j-1,ji,i+1,…,j−1,j的礼物。选出这些礼物的美观程度定义为:

(M(i,j)-m(i,j))/(j-i+k)(M(i,j)−m(i,j))/(j−i+k),其中M(i,j)M(i,j)表示max\{A_i,A_{i+1}....A_j\}max{Ai​,Ai+1​....Aj​},m(i,j)m(i,j)表示min\{A_i,A_{i+1}....A_j\}min{Ai​,Ai+1​....Aj​},K为给定的正整数。

由于不能显得太小气,所以JYY所选礼物的件数最少为L件;同时,选得太多也不好拿,因此礼物最多选R件。JYY应该如何选择,才能得到最大的美观程度?由于礼物实在太多挑花眼,JYY打算把这个问题交给会编程的你。

法一:用单调暴力求解,然后你就可以得到宝贵的20分(本人亲自实验)。

法二(正解):

若区间长度等于规定L,就直接用单调队列维护长度为L的区间的最大值和最小值,分别计算每个区间,用一个ans记录最大值。

若区间大于L,对于一个区间[l, r]很明显可以发现最优的取法是在A[l]为最小值, A[r]为最大值或A[l]为最小值,A[r]为最大值。

然后开始二分答案。

judge函数:

1, A[l] > A[r], 要A[l] - A[r] > (r - l + 1) * mid; 所以若max{A[i] + i * mid - (A[j] - j * mid) - k * mid} >= 0则mid可以更大

2,若A[l] < A[r] 同理,反过来就行。

所有A[i] + i * mid, A[j] - j * mid用单调队列来维护。

#include <bits/stdc++.h>
using namespace std;
const long long MAX = ;
const double INF = 1e9;
long long t, n, k, l, r;
long long a[MAX], q1[MAX], q2[MAX], q[MAX];
double val[MAX];
double ans;
//读入优化
double read() {
double ret = , f = ;
char ch = getchar();
while ('' > ch || ch > '') {
if (ch == '-') f = -;
ch = getchar();
}
while ('' <= ch && ch <= '') {
ret = ret * + ch - '';
ch = getchar();
}
return ret * f;
}
//判断
bool judge(double m) {
double ret = -INF;
for (long long i = ; i <= n; i++) {
val[i] = a[i] - m * i;
}
long long head = , tail = ;
for (long long i = l + ; i <= n; i++) {
while (head <= tail && i - q[head] >= r) head++;
while (head <= tail && val[q[tail]] >= val[i - l]) tail--;
q[++tail] = i - l;
ret = max(ret, val[i] - val[q[head]]);
}
for (long long i = ; i <= n; i++) {
val[i] = a[i] + m * i;
}
head = , tail = ;
for (long long i = n - l; i >= ; i--) {
while (head <= tail && q[head] - i >= r) head++;
while (head <= tail && val[q[tail]] >= val[i + l]) tail--;
q[++tail] = i + l;
ret = max(ret, val[i] - val[q[head]]);
}
//k是题目给的常数
return ret >= k * m;
}
int main() {
t = read();
while (t--) {
ans = -INF;
n = read(), k = read(), l = read(), r = read();
for (long long i = ; i <= n; i++) a[i] = read();
long long h1 = , h2 = , t1 = , t2 = ;
for (long long i = ; i < l; i++) {
while (h1 <= t1 && a[q1[t1]] >= a[i]) t1--;
while (h2 <= t2 && a[q2[t2]] <= a[i]) t2--;
q1[++t1] = q2[++t2] = i;
}
for (long long i = ; i <= n; i++) {
while (h1 <= t1 && i - q1[h1] >= l) h1++;
while (h2 <= t2 && i - q2[h2] >= l) h2++;
while (h1 <= t1 && a[q1[t1]] >= a[i]) t1--;
while (h2 <= t2 && a[q2[t2]] <= a[i]) t2--;
q1[++t1] = q2[++t2] = i;
ans = max(ans, 1.0 * (a[q2[h2]] - a[q1[h1]]) / (l + k - ));
}
//注意精度
double l = , r = ;
while (r - l >= 0.000001) {
double mid = (l + r) / ;
if (judge(mid)) ans = max(ans, mid), l = mid + 0.000001;
else r = mid - 0.000001;
}
printf("%.4lf\n", ans);
}
return ;
}

GDOI#345. 送礼物「JSOI 2015」01分数规划+RMQ的更多相关文章

  1. 送礼物「JSOI 2015」RMQ+01分数规划

    [题目描述] 礼品店一共有N件礼物排成一列,每件礼物都有它的美观度.排在第\(i(1\leq i\leq N)\)个位置的礼物美观度为正整数\(A_I\).JYY决定选出其中连续的一段,即编号为礼物\ ...

  2. LibreOJ 2003. 「SDOI2017」新生舞会 基础01分数规划 最大权匹配

    #2003. 「SDOI2017」新生舞会 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  3. [BZOJ4476] [JSOI2015] 送礼物 (01分数规划+ST表)

    [BZOJ4476] [JSOI2015] 送礼物 (01分数规划+ST表) 题面 给出n,k,l,r和序列a,要求从a中选一段连续的区间[i,j]出来,使得M(i,j)-m(i,j)/(j-i+k) ...

  4. P6087 [JSOI2015]送礼物 01分数规划+单调队列+ST表

    P6087 [JSOI2015]送礼物 01分数规划+单调队列+ST表 题目背景 \(JYY\) 和 \(CX\) 的结婚纪念日即将到来,\(JYY\) 来到萌萌开的礼品店选购纪念礼物. 萌萌的礼品店 ...

  5. [JSOI 2016] 最佳团体(树形背包+01分数规划)

    4753: [Jsoi2016]最佳团体 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2003  Solved: 790[Submit][Statu ...

  6. 【BZOJ4476】[Jsoi2015]送礼物 分数规划+RMQ

    [BZOJ4476][Jsoi2015]送礼物 Description JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物.萌萌的礼品店很神奇,所有出售的礼物都按照特定的顺序都排成 ...

  7. 极光的开源礼物「Aurora IMUI」

    今日,奉上我们拙作,仅为开源世界献出绵薄之力. Aurora IMUI,一个通用的即时通讯(IM)UI 库.不局限于任何 IM SDK. 本 UI 库提供了消息列表.输入视图等常用组件. 初心 过去的 ...

  8. 「HNOI 2015」实验比较

    \(Description\) 有\(n\)个元素,对于每个元素\(x_i\)最多知道一个形如\(x_j < x_i\)或\(x_j=x_i\)的条件,问有多少合法的序列.合法的序列满足每个元素 ...

  9. 「HNOI 2015」亚瑟王

    \(Description\) 有\(n\)张卡牌,每一张卡牌有\(p_i\)的概率发动,并造成\(d_i\)点伤害.一共有\(r\)轮,每一轮按照编号从小到大依次考虑,如果这张牌已经发动过则跳过该牌 ...

随机推荐

  1. C 语言入门第十二章---C语言文件操作

    C语言具有操作文件的能力,比如打开文件.读取和追加数据.插入和删除数据.关闭文件.删除文件等. 在操作系统中,为了同意对各种硬件的操作,简化接口,不同的硬件设备也都被看成一个文件.对这些文件的操作,等 ...

  2. Java 自定义DateUtils

    1 /* Date d = new Date(); String s = DateUtils.DateToString(d, "yyyy-MM-dd HH:mm:ss"); Sys ...

  3. Locale

    1. Locale 概述 2. Windows 区域设置 3 Linux Locale 3.1 Linux Locale 语言环境名称格式 3.2 常用区域描述(简写)日期习惯 3.3 日期显示格式 ...

  4. 使用taglib指令在jsp页面导入要使用的jstl标签库

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

  5. SpringSecurity-权限关联与控制

    6.3 服务器端方法级权限控制 在服务器端我们可以通过Spring security提供的注解对方法来进行权限控制.Spring Security在方法的权限控制上 支持三种类型的注解,JSR-250 ...

  6. Django 学习 之ORM多表操作

    一.创建模型 1.模型关系整理 创建一对一的关系:OneToOne("要绑定关系的表名") 创建一对多的关系:ForeignKey("要绑定关系的表名") 创建 ...

  7. Law of large numbers and Central limit theorem

    大数定律 Law of large numbers (LLN) 虽然名字是 Law,但其实是严格证明过的 Theorem weak law of large number (Khinchin's la ...

  8. 关于Redis 分布式 微服务 集群Cluster

    一:Redis 1,redis是一个高性能的键值对存储方式的数据库,同时还提供list,set,zset,hash等数据结构的存储. 2,Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集 ...

  9. java并发初探ConcurrentHashMap

    java并发初探ConcurrentHashMap Doug Lea在java并发上创造了不可磨灭的功劳,ConcurrentHashMap体现这位大师的非凡能力. 1.8中ConcurrentHas ...

  10. Linux用户和用户组管理命令

    一.用户管理命令 1.useradd   创建用户或更新默认新用户的信息 使用方法  useradd [options] 用户名 选项: useradd -u           指定UID具体数值, ...