zoukankan      html  css  js  c++  java
  • 【bzoj5090】组题 分数规划

    题目描述

    给出一个长度为n的序列,求一段长度大于等于k的字串,使得它们的平均值最大。

    输入

    第一行包含两个整数n,k(1<=n<=100000,1<=k<=n),分别表示题目的总量和题数的下界。

    第二行包含n个整数a_1,a_2,...,a_n(|a_i|<=10^8),分别表示每道题目的难度系数。

    输出

    输出一个既约分数p/q或-p/q,即平均难度系数的最大值。

    样例输入

    5 3
    1 4 -2 -3 6

    样例输出

    5/4


    题解

    分数规划

    二分答案mid,将每个数减去mid后,问题转化为判定性问题:是否存在一个长度大于等于k的字串,使得它们的和非负。

    把区间和转化为前缀相减的形式,求出前缀和。枚举区间右端点 $i$ ,要判定的就是 $sum[i]-min(sum[j])(0le jle i-k)$ 是否大于等于0。存在某一个大于等于0则有解,否则无解。

    但是答案询问的是分数形式怎么办?只需要每次记录答案的选择方式,最后根据这个方式再计算一遍即可。

    时间复杂度 $O(nlog n)$ 

    需要注意的一点是答案可能为负数,因此取gcd时需要取区间和的绝对值计算。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 100010
    using namespace std;
    typedef long long ll;
    int a[N] , n , k , ansl , ansr;
    double sum[N];
    ll gcd(ll a , ll b)
    {
        return b ? gcd(b , a % b) : a;
    }
    bool judge(double mid)
    {
        int i , pos = 0;
        for(i = 1 ; i <= n ; i ++ ) sum[i] = sum[i - 1] + a[i] - mid;
        for(i = k ; i <= n ; i ++ )
        {
            if(sum[i] - sum[pos] >= 0)
            {
                ansl = pos + 1 , ansr = i;
                return 1;
            }
            if(sum[i - k + 1] < sum[pos]) pos = i - k + 1;
        }
        return 0;
    }
    int main()
    {
        int i , cnt = 40;
        ll p = 0 , q , t;
        double l = 1 << 30 , r = -1 << 30 , mid;
        scanf("%d%d" , &n , &k);
        for(i = 1 ; i <= n ; i ++ )
        {
            scanf("%d" , &a[i]);
            l = min(l , 1.0 * a[i]) , r = max(r , 1.0 * a[i]);
        }
        while(cnt -- )
        {
            mid = (l + r) / 2;
            if(judge(mid)) l = mid;
            else r = mid;
        }
        q = ansr - ansl + 1;
        for(i = ansl ; i <= ansr ; i ++ ) p += a[i];
        t = gcd(p > 0 ? p : -p , q);
        printf("%lld/%lld
    " , p / t , q / t);
        return 0;
    }
    

     

  • 相关阅读:
    Maximum Depth of Binary Tree
    Single Number
    Merge Two Sorted Lists
    Remove Nth Node From End of List
    Remove Element
    Remove Duplicates from Sorted List
    Add Two Numbers
    编译视频直播点播平台EasyDSS数据排序使用Go 语言 slice 类型排序的实现介绍
    RTMP协议视频直播点播平台EasyDSS在Linux系统中以服务启动报错can’t evaluate field RootPath in type*struct排查
    【解决方案】5G时代RTMP推流服务器/互联网直播点播平台EasyDSS实现360°全景摄像机VR直播
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8016811.html
Copyright © 2011-2022 走看看