隐藏页面特效

POJ 2018 Best Cow Fences(二分+最大连续子段和)

Best Cow Fences
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 14601   Accepted: 4720

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

Source

 

【题意】

 

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

 

 

【分析】

 

二分答案,判定是否存在一个长度不小于L的子段,平均数不小于二分的值。如果把数列中的每个数都减去二分的值,就转换为判定“是否存在一个长度不小于L的子段,子段和非负”。

 

<==>求一个子段,使得它的和最大,且子段的长度不小于L

 

子段和可以转换为前缀和相减的形式,即设sumj表示Ai~Aj的和,

 

则有:max{A[j+1]+A[j+2].......A[i] } ( i-j>=L ) = max{ sum[i] - min{ sum[j] }(0<=j<=i-L) }L<=i<=n

 

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

 

【代码】

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=1e5+5; int n,m;double a[N],b[N],sum[N]; double l,r,mid,eps=1e-6; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lf",a+i),l=min(l,a[i]),r=max(r,a[i]); while(r-l>eps){ mid=(l+r)/2; 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 res=-1e10,mn=1e10; for(int i=m;i<=n;i++){ mn=min(mn,sum[i-m]); res=max(res,sum[i]-mn); } if(res>=0) l=mid; else r=mid; } printf("%d\n",int(r*1000)); return 0; }

 

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/10415470.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(375)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
历史上的今天:
2017-02-21 [SPOJ705]不同的子串
2017-02-21 [JLOI2014]松鼠的新家
2017-02-21 [HAOI2012]外星人
2017-02-21 [HAOI2012]音量调节
2017-02-21 [HAOI2012]外星人
点击右上角即可分享
微信分享提示