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 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块田地,每块田地有cows【i】头牛,求出一个长度不小于F的子段,使子段牛的平均数最大。
思路:我们令 avr = sum【i,j】/(i-j+1)
那么这题就是 求是avr的最大值,我们二分枚举ans,判断 avr 是否不小于 ans,即avr >= ans,为了不维护(i-j+1)的值,变形成sum【i,j】 - ans*(i-j+1) >= 0,
我们把原数组cows【i】-ans,那么Sum【i,j】 = sum【i,j】-ans(i-j+1)。
现在关键就是取得一个  max{Sum【i,j】},对于Sum【i,j】,我们可以用前缀和相减的方式求得,sum(i)-min(sum(j)), 0 <= j <= i-F。 坑点:注意最后答应的是二分的R值,我打印L值Wa的怀疑人生.而且题目要求精度是1e-4,当我们枚举的精度不小于题目要求精度的时候L和R值都是OK的
我感觉是如果两个值转换为整数不同的话,R值转换的整数值在L~R区间内的,而l转换的值是小于l的,如果两个值转换的值相同,打印那个都行,且整数肯定小于L。 其实像是最大值最小,最小值最大,都可以用二分解决,答案是单调的,这题还有种用凸包方法写的,以后再填坑吧。
 #include<cstdio>
#include<iostream>
using namespace std; const int maxn = 1e5+;
int n,f;
int cows[maxn];
const double eps = 1e-; bool solve(double x,int f)
{
double fcows[n+];
double sum[n+];
for(int i=;i<=n;i++)fcows[i] = cows[i] - x;
for(int i=;i<=n;i++)sum[i] = sum[i-]+fcows[i];
double ans = -1e10,minn = 1e10;
for(int i=f;i<=n;i++)
{
minn = min(minn,sum[i-f]);
ans = max(ans,sum[i]-minn);
}
return ans >= ;
}
int main()
{
scanf("%d%d",&n,&f);
double low=;
double high = ;
for(int i=;i<=n;i++)
{
scanf("%d",&cows[i]);
high += cows[i];
}
while(low + eps < high)
{
double mid = (low+high)/;
if(solve(mid,f))low = mid;
else high = mid;
}
printf("%d\n",(int)(*high));
}

上一篇:用命令查看Mysql中数据库、表的空间大小


下一篇:Unity3d学习 相机的跟随