题目描述

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. jvm学习:类的加载、连接、初始化、常量

    类在jvm中有这几个过程类的加载.连接.初始化.使用.卸载 类的加载 类的加载是将class文件中的二进制数据加载到内存中,将其放在运行时的数据区:方法区内,然后在内存中创建一个 java.lang. ...

  2. 简析ThreadLocal原理及应用

    简析ThreadLocal原理及应用 原创: 东晨雨 JAVA万维猿圈 4月17日 ThreadLocal的源码加上注释不超过八百行,源码结构清晰,代码也比较简洁.ThreadLocal可以说是Jav ...

  3. Flask - 数据库相关

    1. Flask-SQLAlchemy 1.1 参考: http://flask-sqlalchemy.pocoo.org/2.3/ https://github.com/janetat/flasky ...

  4. Abstract Data Type

  5. Wepy框架和mpVue框架的比较及使用mpVue框架需要注意的点

    Wepy框架 它是一款类Vue框架,在代码风格上借鉴了Vue,本身和Vue没有任何关系. mpVue框架 它是从整个Vue的核心代码上经过二次开发而形成的一个框架,相当于是给Vue本身赋能,增加了开发 ...

  6. 数据库事务ACID特效

    一.数据库事务正确执行的4个基础要素: 1.原子性 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状 ...

  7. ROS学习笔记6-理解主题

    本文来源于:http://wiki.ros.org/ROS/Tutorials/UnderstandingTopics ROS主题假设turtlesim节点已经运行,打开一个新终端,使用如下命令运行键 ...

  8. 关于req.params、req.query、req.body等请求对象

    请求对象,通常传递到回调方法,这意味着你可以随意命名,通常命名为 req 或 request . 请求对象中最常用的属性和方法有: req.params 一个数组,包含命名过的路由参数. req.pa ...

  9. 嵌入式 printf的实现

    在嵌入式中,经常需要用到printf来调试程序 标准库函数的默认输出设备是显示器,要实现在串口或LCD输出,必须重定义标准库函数里调用的与输出设备相关的函数. printf输出到串口,需要将fputc ...

  10. luogu P2762 太空飞行计划问题

    好像是最大权闭合图,也就是最大流最小割啦,找出最大流的路径输出,这题如何建模呢,一样的先设源点和汇点,源点向每个计划连capacity为赞助数的边,每个计划连相应装置capacity为无穷的边,每个装 ...