[AcWing 4502] 集合操作

image
image

单调性


点击查看代码
#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 1e6 + 10;

int n, m, op;
int a[N];

void solve()
{
    scanf("%d", &m);
    double sum = 0;
    int k = 0;
    while (m --) {
        scanf("%d", &op);
        if (op == 1) {
            scanf("%d", &a[++ n]);
            sum += a[n] - a[n - 1];
        }
        else {
            while (k < n && a[k + 1] <= sum / (k + 1))
                sum += a[++ k];
            printf("%.10f\n", a[n] - sum / (k + 1));
        }
    }
}

signed main()
{
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);
    // cout.tie(nullptr);

    solve();

    return 0;
}

  1. 当最大值确定时,选的是满足条件的前缀
    设数组为 a1,a2,axax 是目前所选的最大值,要保证平均值最小,应尽可能多的选一些值较小的元素,数组是单调递增的,除 ax 外,所选的其他值应是数组的前缀,设 x¯1=i=1kai+axk+1x¯2=i=1k+1ai+axk+2,令 x¯1x¯2, 解得 ak+1x¯1,在满足 ak+1x¯1 的情况下,将 ak+1 加入平均值,总能使平均值变小,所以当最大值确定时,要让平均值最小,应取满足 aix¯ 的最长的前缀
  2. 最大值应选当前数组的最后一项元素
    不妨设 x1<x2,当选 x1 时,目标函数为 y1=x1i=1kai+x1k+1=kx1k+1+i=1kaik+1,当选 x2 时,一定也可以选到 k 这个位置,选 k 这个位置时的目标函数为 y2=x2i=1kai+x2k+1=kx2k+1+i=1kaik+1,可以发现 y1<y2,选后一项一定比前一项更优,故最大值应选当前数组的最后一项元素
posted @   wKingYu  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
欢迎阅读『[AcWing 4502] 集合操作』
点击右上角即可分享
微信分享提示