列表

详情


NC20220. [JSOI2015]送礼物

描述

JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物。 萌萌的礼品店很神奇,所有出售的礼物都按照特定的顺序都排成一列,而且相邻的礼物之间有一种神秘的美感。于是,JYY决定从中挑选连续的一些礼物,但究竟选哪些呢? 
【问题描述】 假设礼品店一共有N件礼物排成一列,每件礼物都有它的美观度。排在第i 1 ≤ i ≤ N个位置的礼物美观度为正整数Ai,。JYY决定选出其中连续的一段, 即编号为礼物i,i+1,…,j-1,j的礼物。
选出这些礼物的美观程度定义为 (M(i,j)-m(i,j))/(j-i+k) 其中M(i,j)表示max{Ai,Ai+1....Aj},m(i,j)表示min{Ai,Ai+1....Aj},K为给定的正整数。 
由于不能显得太小气,所以JYY所选礼物的件数最少为L件;同时,选得太多也不好拿,因此礼物最多选R件。
JYY应该如何选择,才能得到最大的美观程度?由于礼物实在太多挑花眼,JYY打算把这个问题交给会编程的你。

输入描述

本题每个测试点有多组数据。输入第一行包含一个正整数T(T ≤ 10),表示有T组数据。 
每组数据包含两行,第一行四个非负整数N,K,L,R(2 ≤ L ≤ R ≤ N。
第二行包含N个正整数,依次表示A1,A2....An,(Ai ≤ 10^8),N,K ≤ 50,000

输出描述

输出T行,每行一个非负实数,依次对应每组数据的答案,数据保证答案不会超过10^3。输出四舍五入保留4位小数。

示例1

输入:

1
5 1 2 4
1 2 3 4 5

输出:

0.7500

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 337ms, 内存消耗: 1144K, 提交时间: 2019-03-09 18:15:53

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
typedef double f2;
#define eps 1e-7
#define N 50050
int n,a[N],K,L,R,Q1[N],l1,r1,Q2[N],l2,r2,Q3[N],l3,r3;
f2 t[N];
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d%d%d",&n,&K,&L,&R);
        int i;
        for(i=1;i<=n;i++) scanf("%d",&a[i]);
        l1=r1=l2=r2=0;
        for(i=1;i<L;i++) {
            while(l1<r1&&a[Q1[r1-1]]>=a[i]) r1--;
            while(l2<r2&&a[Q2[r2-1]]<=a[i]) r2--;
            Q1[r1++]=Q2[r2++]=i;
        }
        f2 ans1=-1000;
        for(i=L;i<=n;i++) {
            while(l1<r1&&i-Q1[l1]>=L) l1++;
            while(l2<r2&&i-Q2[l2]>=L) l2++;
            while(l1<r1&&a[Q1[r1-1]]>=a[i]) r1--;
            while(l2<r2&&a[Q2[r2-1]]<=a[i]) r2--;
            Q1[r1++]=Q2[r2++]=i;
            ans1=max(ans1,1.0*(a[Q2[l2]]-a[Q1[l1]])/(L-1+K));
        }
        f2 l=0,r=1000;
        while(r-l>eps) {
            f2 mid=(l+r)/2;
            f2 re=-100000;
            l3=r3=0;
            for(i=1;i<=n;i++) t[i]=a[i]-i*mid;
            for(i=L+1;i<=n;i++) {
                while(l3<r3&&i-Q3[l3]>=R) l3++;
                while(l3<r3&&t[Q3[r3-1]]>=t[i-L]) r3--;
                Q3[r3++]=i-L; re=max(re,t[i]-t[Q3[l3]]);
            }
            l3=r3=0;
            for(i=1;i<=n;i++) t[i]=a[i]+i*mid;
            for(i=n-L;i;i--) {
                while(l3<r3&&Q3[l3]-i>=R) l3++;
                while(l3<r3&&t[Q3[r3-1]]>=t[i+L]) r3--;
                Q3[r3++]=i+L; re=max(re,t[i]-t[Q3[l3]]);
            }
            if(re>=mid*K) l=mid;
            else r=mid;
        }
        //printf("%.4f\n",ans1);
        printf("%.4f\n",max(ans1,l));
    }
}

上一题