poj2018——Best Cow Fences

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

题意:

给定一个正整数序列a,求一个平均数最大的、长度不小于L的子段。

Solution:

本题由于是求平均数的最大值,我们很容易往二分方向上想,二分答案的关键是如何取check,判定“是否存在一个长度不小与L的子段平均数不小于二分的值”。

考虑这样一种思路,把数列中每个数都减去二分的值,就转化为判断是否存在一个长不小于L的子段,子段和非负。继续思考,

1、若没有L的限制,只需O(n)扫描数列不断加数当和为负数时就把当前子段清空,扫描过程中出现过的最大子段和即为所求。

2、求一个子段它的和最大且长度不小与L。子段和可以转化为前缀和相减的形式,即设sumi表示ai~aj的和,则:

仔细观察上面的式子容易发现,随着i的增长,j的取值范围0~i-L每次只会增大1。换言之,每次只会有一个新的取值进入min{sumj}的候选集合,所以我们没有必要每次循环枚举j,只需要用一个变量记录当前的最小值,每次与新的取值sumi-L取min就可以了。

于是我们只需要看一下最大子段和是不是非负数就可以确定二分上下界的变化范围了。

(没看懂没事,第一遍我也没看懂,仔细看并对照代码,f**k真的简单巧妙!)

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<cstdlib>
 6 #define il inline
 7 #define ll long long
 8 #define debug printf("%d %s\n",__LINE__,__FUNCTION__)
 9 using namespace std;
10 il int gi()
11 {
12     int a=0;char x=getchar();bool f=0;
13     while((x<‘0‘||x>‘9‘)&&x!=‘-‘)x=getchar();
14     if(x==‘-‘)x=getchar(),f=1;
15     while(x>=‘0‘&&x<=‘9‘)a=a*10+x-48,x=getchar();
16     return f?-a:a;
17 }
18 const double eps=1e-6;
19 int n,L;
20 double a[100001],b[100001],sum[100001];
21 int main()
22 {
23     n=gi(),L=gi();
24     for(int i=1;i<=n;i++)a[i]=gi();
25     double l=-1e6,r=1e6;
26     while(r-l>eps){
27         double mid=(l+r)/2,ans=-1e10,minn=1e10;
28         for(int i=1;i<=n;i++)b[i]=a[i]-mid;
29         for(int i=1;i<=n;i++)sum[i]=sum[i-1]+b[i];
30         for(int i=L;i<=n;i++)minn=minn<sum[i-L]?minn:sum[i-L],ans=max(ans,sum[i]-minn);
31         if(ans>=0)l=mid;else r=mid;
32     }
33     printf("%d\n",int(r*1000));
34     return 0;
35 }

原文地址:https://www.cnblogs.com/five20/p/8516346.html

时间: 2024-10-12 10:37:40

poj2018——Best Cow Fences的相关文章

POJ2018 Best Cow Fences

Best Cow Fences Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 11175   Accepted: 3666 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 <

POJ2018 Best Cow Fences 二分答案/DP

显然二分答案,然后减去对应的mid,求超过L的最大子段和验证就好了. 当然记录下长度的直接DP也是可以的. 然而二分答案怎么都WA,很好奇为什么 直接输出r反而是能过的. 看了下https://blog.csdn.net/jiangshibiao/article/details/21963437 想起来double取整输出的时候要加上eps 1 https://blog.csdn.net/jiangshibiao/article/details/21963437 原文地址:https://www

POJ 2018 Best Cow Fences

斜率优化DP...<浅谈数形结合思想在信息学竞赛中的应用 安徽省芜湖一中 周源>例题... Best Cow Fences Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9311   Accepted: 2986 Description Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field c

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 nu

一本通 1434:【例题2】Best Cow Fences

Best Cow Fences 二分答案 + 前缀和 个人认为题意没有表述清楚,本题要求的是满足题意的连续子序列(难度大大降低了有木有). 本题的精度也是非常令人陶醉,请您自行体会吧! #include <iostream> #include <cstdio> #include <algorithm> using namespace std; //Mystery_Sky // #define M 10000100 #define ex 1e-5 double l = 1

poj 动态规划DP - 2018 Best Cow Fences

这道题目我一开始的思路是用二维DP,结果TLE了.后来换了个思路,终于AC了. 不需要判断所有的情况,我们用dp[i]表示前i个牛圈中最大的牛数,而这个i首先必须>=限制的牛圈树f.用num[i]表示dp[i]中包含了多少牛圈. 我们可以知道,dp[i] = sum[i] - sum[i-f])/f  or  dp[i-1] + data[i], 前一个代表到i为止前f个牛圈的牛数,后一个代表前i-1个牛圈中最大牛数+第i个牛圈中的牛数.其实也就是到i为止前num[i-1]+1个牛圈的牛数.而判

G - Best Cow Fences (POJ - 2018)

- 题目大意 给你n个牛的自身价值,让你找出连续的且数量大于等于F的一段区间,使这段区间内的牛的平均价值最大. - 解题思路 这道题可以用二分法也可以结合前缀数组来求和来做,我就是用前缀数组求和和二分答案法来做的. - 代码 #include <iostream> #include <algorithm> using namespace std; const int maxn = 1e5 + 10; int sum[maxn]; int main() { int n, f, a;

Best Cow Fences POJ - 2018

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 nu

POJ 2018 Best Cow Fences(二分最大区间平均数)题解

题意:给出长度>=f的最大连续区间平均数 思路:二分这个平均数,然后O(n)判断是否可行,再调整l,r.判断方法是,先求出每个数对这个平均数的贡献,再求出长度>=f的最大贡献的区间,如果这个最大贡献大于0说明这个二分出来的数可行. 代码: #include<set> #include<map> #include<stack> #include<cmath> #include<queue> #include<vector>