zoukankan      html  css  js  c++  java
  • COW

    COW:

    题目描述:

    Xiaoming's farm consists of a long row of N (1≤N≤100,000) fields. Each field contains a certain number of cows,0≤ncows≤2000.  Xiaoming wants to build a fence around a contiguous group of these fields in order to maximize the average number of cows per field within that block. The block must contain at least F (1≤F≤N) fields, where F given as input.  Calculate the fence placement that maximizes the average, given the constraint.

    输入:

    Line 1: Two space-separated integers, N and F.

    Lines 2..N+1: Each line contains a single integer, the number of cows in a field. Line 2 gives the number of cows in field 1,line 3 gives the number in field 2, and so on.

    样例输入:

    10 6
    6 
    4
    2
    10
    3
    8
    5
    9
    4
    1
    

    样例输出:

    6500
    

    题解:

    ​ 题目大意:给出一个长度为n的数组,求其中长度不小于f的子序列的最大平均值。

    ​ 这是一道二分题,这里二分答案即最大平均值,然后我们对于每一个二分值判断在序列中能否找到一段长度不小于f的子序列其平均值大于等于二分结果,如果存在则结果可以更大,所以取l=mid,否则结果更小,所以取r=mid 。对于这题最难想的应该是如何判断区间是否存在一段长度不小于f的序列的平均值大于等于此时二分值。如果说对于一段区间其平均值大于等于mid,那么应该有区间和减去平均值乘以区间长度的结果大于等于0,即,(sum_{i=l}^r{sum[i]}-mid*(r-l+1)=sum_{i=l}^r{(sum[i]-mid)}>=0),由此想到用前缀和来处理,因为,我们只需找到区间最大的平均值满足条件即可,所以可以在O(n)下找到最大值,配合二分总的时间复杂度在O(log(2000)×n)。

    /******************************************
    /@Author: LeafBelief
    /@Date: 2020-03-07
    /@Remark:    
    /@FileName: cowsol
    ******************************************/
    #include <bits/stdc++.h>
    #define CSE(x, y) memset(x, y, sizeof(x))
    #define lowbit(x) (x & (-x))
    #define INF 0x3f3f3f3f
    #define FAST                     
        ios::sync_with_stdio(false); 
        cin.tie(0);
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
    
    const int maxn = 111111;
    int n, f;
    double sum[maxn], arr[maxn];
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("in.in", "r", stdin);
    #endif
        FAST;
        CSE(sum, 0);
        CSE(arr, 0);
        cin >> n >> f;
        for (int i = 1; i <= n; i++)
        {
            cin >> arr[i];
        }
        double l = 0, r = 2002;
        while (r - l > (1e-6))//扩大1000倍后保证数据准确性,所以进度开到了1e-6
        {
            double mid = (l + r) / 2.0;
            double mn = INF;
            double mx = -INF;
            for (int i = 1; i <= n; i++)
            {
                sum[i] = sum[i - 1] + arr[i] - mid;//处理计算平均值的前缀和
            }
            //计算最大区间平均值
            for (int i = f; i <= n; i++)
            {
                mn = min(mn, sum[i - f]);//维护从当前位置向前的最小左端点
                mx = max(mx, sum[i] - mn);//用当前前缀和减去最小的左端点为当前的最大区间平均值,用mx不断取最大来维护结果
            }
            if (mx >= 0)//判断结果是否满足存在区间平均值大于等于当前结果
                l = mid;
            else
                r = mid;
        }
        cout << int(r * 1000) << endl;
        return 0;
    }	
    
  • 相关阅读:
    2020暑假项目-车辆派遣管理系统开发记录#8
    2020暑假项目-车辆派遣管理系统开发记录#7
    2020暑假项目-车辆派遣管理系统开发记录#6
    2020暑假项目-车辆派遣管理系统开发记录#5
    2020暑假项目-车辆派遣管理系统开发记录#4
    2020暑假项目-车辆派遣管理系统开发记录#3
    持续交付工具ThoughtWorks Go部署step by step
    mysql千万级大数据SQL查询优化
    分享MYSQL中的各种高可用技术(源自姜承尧大牛)
    我的MYSQL学习心得(十七) 复制
  • 原文地址:https://www.cnblogs.com/LeafLove/p/12433032.html
Copyright © 2011-2022 走看看