Codeforces 578C Weakness and Poorness(二分 + 最大(小)子段和)

网上很多人写这道题目是三分+最大(小)子段和,但是这道题目是可以二分的,看我的二分内容

//我们的目的是让最小字段和和最大字段和相等
bool Calc(double x)
{
//MN、MX分别是最小最大子段和
    if(MN > eps) return 1;     //当最小子段和比0大时减小(-x)(ps:我是写的a[i] = a[i]+x)
    if(MX < eps) return 0;     //当最大子段和比0小时增大(-x)
    return fabs(MN) - MX < eps;//当最小子段和比最大子段和小的时候让(-x)减小,反之增大。
}
//以下是二分部分
        mid = (l + r) / 2.0;
        if(Calc(mid)) r = mid;
        else l = mid;

给出完整代码:

#include<cstdio>
#include<cmath>
#define max(a, b) (a) > (b) ? (a) : (b)
#define min(a, b) (a) < (b) ? (a) : (b)
#define MAXN 200005
#define eps 1e-12
int n;
double a[MAXN], MX, tmpx, MN, tmpn;
bool Calc(double x)
{
    MX = MN = tmpn = tmpx = a[1] + x;
    for(int i = 2; i <= n; i ++) {
        tmpx = max(tmpx + a[i] + x, a[i] + x);
        MX = max(tmpx, MX);
        tmpn = min(tmpn + a[i] + x, a[i] + x);
        MN = min(tmpn, MN);
    }
    if(MN > eps) return 1;
    if(MX < eps) return 0;
    return fabs(MN) - MX < eps;
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)
        scanf("%lf", a + i);
    double l = -10000.0000001, r = 10000.0000001, mid;
    for(int i = 1; i <= 60; i ++) {
        mid = (l + r) / 2.0;
        if(Calc(mid)) r = mid;
        else l = mid;
    }
    printf("%.9lf", MX);
    return 0;
}

转载于:https://www.cnblogs.com/geng4512/p/5296904.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值