BZOJ_3477_[Usaco2014 Mar]Sabotage_二分
题意:
约翰的牧场里有 N 台机器,第 i 台机器的工作能力为 Ai。保罗阴谋破坏一些机器,使得约翰的工作效率变低。保罗可以任意选取一段编号连续的机器,使它们停止工作。但这样的破次,而且保罗无法破坏第一台或最后一台机器。请问他该破坏哪些机器才能让剩下机器的工作效率的平均数最小?为了显示存在感,保罗至少必须破坏一台机器。
分析:
二分推式子好题。二分出答案k,将a[i]-k,求出2到n-1最大子段和mx。用sum-mx既是剩下的前一段后一段的和。如果小于0则是合法的。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 #define N 100050 6 #define du double 7 int a[N],n; 8 du sum; 9 bool check(du x) 10 { 11 du ans=-100000,f=-100000; 12 for(int i=2;i<n;i++) 13 { 14 du now=a[i]-x; 15 f=max(now,f+now); 16 ans=max(ans,f); 17 } 18 if(sum-x*n-ans<=0)return 1; 19 return 0; 20 } 21 int main() 22 { 23 scanf("%d",&n); 24 for(int i=1;i<=n;i++) 25 { 26 scanf("%d",&a[i]); 27 sum+=a[i]; 28 } 29 du l=0,r=1000000; 30 for(int i=1;i<=60;i++) 31 { 32 du mid=(l+r)*0.5; 33 if(check(mid))r=mid; 34 else l=mid; 35 } 36 printf("%.3lf",l); 37 }