3477: [Usaco2014 Mar]Sabotage

来源:互联网 发布:北京凶宅数据库查询 编辑:程序博客网 时间:2024/05/21 06:44

题目链接

题目大意:给你N个数,第一个和最后一个不能去掉。
现希望去掉中间某段连续的数,使得剩下的数的平均值最小化

题解:最大/最小化平均数->二分平均数,然后每个数二分值,搞一搞是否大于0

对于这题,先减去平均值,求最大连续子段和mx
那么此时序列由 L + mx + R组成. L + mx + R = sum - n * m, sum为原序列的和.

假如二分的答案m是可行的, 那么 L + R = sum - n * m - mx 应该 <= 0

我的收获:科学二分姿势

#include <cstdio>#include <cstring>#include <iostream>using namespace std;#define eps 1e-9int a[100005];double maxx,tot,s,sum;double l,r,mid,ans;int n,k;bool check(double m) {    double p = 0, B, mx = -1e10;    for(int i=2;i<n;i++) {        B = a[i] - m;        if(p >= 0) B += p;        mx = max(mx, p = B);    }    return sum - n * m - mx <= 0;}void init(){    scanf("%d",&n);    for(int i=1;i<=n;++i)    {        scanf("%d",&a[i]);        sum+=a[i];    }}void work(){    l=0,r=1e9;    while(r-l>=eps)    {        mid=(l+r)/2.0;        if(check(mid))        r=mid,ans=mid;        else l=mid;    }    printf("%.3lf",ans);}int main(){    init();    work();    return 0;}
原创粉丝点击