1. 程式人生 > >Best Cow Fences POJ - 2018

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。

其實像是最大值最小,最小值最大,都可以用二分解決,答案是單調的,這題還有種用凸包方法寫的,以後再填坑吧。

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 
 5 const int maxn = 1e5+5;
 6 int n,f;
 7 int cows[maxn];
 8 const double eps = 1e-8;
 9 
10 bool solve(double x,int f)
11 {
12     double fcows[n+1];
13     double sum[n+1];
14     for(int i=1;i<=n;i++)fcows[i] = cows[i] - x;
15     for(int i=1;i<=n;i++)sum[i] = sum[i-1]+fcows[i];
16     double ans = -1e10,minn = 1e10;
17     for(int i=f;i<=n;i++)
18     {
19         minn = min(minn,sum[i-f]);
20         ans = max(ans,sum[i]-minn);
21     }
22     return ans >= 0;
23 }
24 int main()
25 {
26     scanf("%d%d",&n,&f);
27     double low=0;
28     double high = 0;
29     for(int i=1;i<=n;i++)
30     {
31         scanf("%d",&cows[i]);
32         high += cows[i];
33     }
34     while(low + eps < high)
35     {
36         double mid = (low+high)/2;
37         if(solve(mid,f))low = mid;
38         else high = mid;
39     }
40     printf("%d\n",(int)(1000*high)); 
41 }
View Code