AcWing 102. 最佳牛围栏 题解

题意





看着不像是二分但是却能用二分做,这里二分是查找浮点型答案,所以结束条件是r和l的误差在某个小数之间就行了。

因为是平均数所以可以利用当前数字和平均数的差构成的前缀和来判断这段区间的平均值是否满足查找的平均数。
具体的check方法就是,枚举区间,循环枚举右端点。
数和平均值的差的最优和就是
d[r]-min(d[1~l])
(l=r-len)len是区间长度
大概就这样把

1
#include<bits/stdc++.h> 2 #define to_l(a) ((a)<<1) 3 #define to_r(a) ((a)<<1|1) 4 #define lowbit(a) ((a)&(-a)) 5 using namespace std; 6 typedef long long int ll; 7 typedef unsigned long long int ull; 8 const int int_inf=0x3f3f3f3f; 9 const ll ll_inf=0x3f3f3f3f3f3f3f3f; 10 const int max_n=1e5+5; 11 int num[max_n]; 12 double sum[max_n]; 13 int n,m; 14 bool check(double avg) 15 { 16 int i,j; 17 sum[0]=0.0; 18 for(i=1;i<=n;i++){ 19 sum[i]=sum[i-1]+(1.0*num[i]-avg); 20 } 21 double minl=sum[0]; 22 for(i=1,j=m;j<=n;j++,i++){ 23 minl=min(minl,sum[i-1]); 24 if(sum[j]-minl>=0) return true; 25 } 26 return false; 27 } 28 int main() 29 { 30 ios::sync_with_stdio(false); 31 cin.tie(0); 32 int i,j; 33 cin>>n>>m; 34 int max1=-1; 35 for(i=1;i<=n;i++){ 36 cin>>num[i]; 37 max1=max(max1,num[i]); 38 } 39 double l=0.9,r=1.0*max1; 40 double ans; 41 while(r-l>1e-5){ 42 double mid=(l+r)/2; 43 if(check(mid)) ans=mid,l=mid; 44 else r=mid; 45 } 46 cout<<(int)((ans+1e-5)*1000)<<endl; 47 return 0; 48 }

 

posted @ 2020-09-11 21:24  Alpaca00  阅读(171)  评论(0)    收藏  举报