102. 最佳牛圍欄 AcWing
阿新 • • 發佈:2020-12-20
字首和+二分答案+雙指標
暴力的思路是:
我們假設mid為答案,先列舉地的數量,列舉區域開始的起始下標,判斷是否有區域的平均值總數大於mid,有就是錯解;
優化:
比較區域平均值大小可以變成假設mid為該區域的平均值,再乘總數作差,如果為負則此答案不正確,這裡可以再優化為求字首和時,每個a[i]都減去mid,再求字首和
當起始座標可以取幾個時,只要有一個符合方案就可返回true
當列舉地數時可以優化為雙指標,雖然i、j在向前移動,可以用變數記錄i的最小值,只要sum[j]>sum[i[說明答案正確
需要注意的是:
因為本道題是向下取整,low與high雖然非常接近,但用low會損失精度,因此用high
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5+10; 4 const double ep = 1e-6; 5 int n,f,a[N],sum[N]; 6 bool check(double mid) 7 { 8 for(int i=1;i<=n;i++) sum[i] = sum[i-1]-mid; 9 double minv = 0; 10 for(int i=0,j = f;j<=n;i++,j++){ 11 minv = min(sum[i],minv);12 if(sum[j]>=minv) return true; 13 } 14 return false; 15 } 16 int main() 17 { 18 scanf("%d%d",&n,&f); 19 for(int i=1;i<=n;i++) { scanf("%d",&a[i]);} 20 double low = 1; double high = 2000; 21 while(high-low>ep){ 22 double mid = (low+high)/2;23 if(check(mid)) low = mid; 24 else high = mid; 25 } 26 printf("%d",(int)high*1000); 27 return 0; 28 }