【bzoj】3477: [Usaco2014 Mar]Sabotage 01分数规划

这题算是01分数规划吧2333

sum-a[i]*x[i]=c*(n-x[i]) 化简一下就是sum-(a[i]-c)*x[i]-nc=0,每次找最大的(a[i]-c)*x[i](子段和),如果结果<=0就是存在方案使sum-a[i]*x[i]=c*(n-x[i])。

注意要至少选一个……

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100500
#define rep(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
double num[maxn],eps=0.00005;
int n; 

bool check(double mid)
{
    double sum=num[1]-mid,ans=num[2]-mid,big=num[1]-mid;
    rep(i,2,n-1) {
        sum+=num[i]-mid;
        if (sum-big>ans) ans=sum-big;
        if (sum<big) big=sum;
    }
    sum+=num[n]-mid;
    return sum-ans<=0;
}

int main()
{
    scanf("%d",&n);
    rep(i,1,n) scanf("%lf",num+i);
    double l=0,r=10000;
    while (r-l>=eps) {
        double mid=(l+r)/2;
        check(mid)?r=mid:l=mid;
    }
    printf("%.3lf\n",r);
    return 0;
}
View Code

 

posted @ 2017-03-11 15:47  Macaulish  阅读(134)  评论(0编辑  收藏  举报