POJ 2018 Best Cow Fences(二分答案)

POJ 2018 Best Cow Fences(二分答案)

Best Cow Fences
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 12144 Accepted: 3958
Description

Farmer John's farm consists of a long row of N (1 <= N <= >100,000)fields. Each field contains a certain number of cows, >1 <= ncows <= 2000.

FJ 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.
Input

  • 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.
    Output
  • Line 1: A single integer that is 1000 times the maximal >average.Do not perform rounding, just print the integer that >is 1000*ncows/nfields.
    Sample Input

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

6500


题意: N, F。n个数,求一个长度大于F的序列,平均数最大。输出平均数乘1000


思路: 二分答案,对于【L,R】区间中的mid,求是否有一个长度大于F的序列平均数大于mid.来缩小区间

把序列减去mid,问题就变成了是否存在一个长度大于F的序列,最大字段和大于零。没有长度限制,最大子段和的DP问题。有了长度限制可以转化为前缀和sum[r] - sum[l - 1] ,我们用前缀和维护一个长度大于F的序列,维护一下前缀和的最小值。

    double ans = -1e9;
    double min_val = 1e9;
    for(int i = L; i <= N; i++ ) {
        min_val = min(min_val, sum[i - L]);
        ans = max(ans, sum[i] - min_val);
    }
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
const int MAXN = 1e5 + 7;
const double EPS = 1e-5;


int N, L;

double a[MAXN], b[MAXN], sum[MAXN];

int main()
{
    while(~scanf("%d %d", &N, &L)) {
        for(int i = 1; i <= N;i ++ ) {
            scanf("%lf", &a[i]);
        }
        double l = -1e8, r = 1e8;
        while(l + EPS < r) {
            double mid = (l + r) / 2.0;
            for(int i = 1; i <= N; i++ ) {
                b[i] = a[i] - mid;
            }
            for(int i = 1; i <= N; i++ ) {
                sum[i] = (sum[i - 1] + b[i]);
            }
            double ans = -1e9;
            double min_val = 1e9;
            for(int i = L; i <= N; i++ ) {
                min_val = min(min_val, sum[i - L]);
                ans = max(ans, sum[i] - min_val);
            }
            if(ans >= 0) {
                l = mid;
            } else {
                r = mid;
            }
        }
        printf("%d\n", int(r * 1000));
    }
    return 0;
}
全部评论

相关推荐

bg27强双非本,目前在学习golang后端gin框架部分,在b站找了一个轮子项目敲了一下,技术栈是gin&nbsp;+&nbsp;gorm&nbsp;+&nbsp;mysql&nbsp;+&nbsp;redis。我目前的想法是这一个月学习408和go八股以及刷算法然后在12月找个寒假实习然后大三下开始准备考研。我是考研意愿比较强烈,想问一下我是应该all&nbsp;in其中一个方向吗,我感觉我实习对我考研来说也是没什么帮助的好像。
牛客28967172...:毕业工作,考研,考公是完全不同的方向。 99%的人拼尽全力也只能把一个做好(能做好都已经是佼佼者了,比如进进大厂,考985或者考公) 如果你确定要考研可以不用学任何就业技术框架,也不用实习经验,刷题背知识点就行,但注意必须考92院校起步,因为这个年代双非硕毕业后完全不如双非本(互联网行业),可以说双非硕在互联网就业完全是负收益
投递哔哩哔哩等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务