codeforces 578c - weekness and poorness - 三分

2017-08-27 17:24:07

writer:pprp

题意简述:

• Codeforces 578C Weakness and poorness
• 给定一个序列A
• 一个区间的poorness定义为这个区间内和的绝对值
• weakness等于所有区间最大的poorness
• 求一个x使得,序列A全部减x后weakness最小
• 1 ≤ n ≤ 2 * 1e5

 

这里用到了最大连续区间的和的知识点·,可以看上一篇博客

通过三分找最小值

AC代码如下:

/*
@theme:myprogramme codeforces 578c
@writer:pprp
@declare:三分的思想
@date:2017/8/27
*/
#include <bits/stdc++.h>

using namespace std;
int n;
const int maxn = 2e6+100;
double a[maxn], b[maxn];
const double eps = 3e-12;

//找到连续区间大和
double maxSum(double a[])
{
    double ans = 0, tmp = 0;
    for(int i = 0; i < n ; i++)
    {
        tmp = max(0.0,tmp) + a[i];
        ans = max(ans, tmp);
    }
    return ans;
}

//对三分的结果进行判断
double calc(double x)
{
    for(int i= 0 ; i < n ; i++)
    {
        b[i] = a[i] - x;
    }
    double as1 = maxSum(b);
    for(int i= 0 ; i < n ; i++)
    {
        b[i] *= -1;
    }
    double as2 = maxSum(b);
    return max(as1, as2);
}

//三分查找
double  Search()
{
    double l = -1e4, r = 1e4;
    double m, mm;
    while(r - l > eps)
    {
        m = (l*2 + r)/3.0;
        mm = (r*2 + l)/3.0;
        double as1 = calc(m);
        double as2 = calc(mm);
        if(as1 < as2)
            r = mm;
        else
            l = m;
    }
    //找到r对应的区间和最大
    return calc(r);
}

int main()
{
    scanf("%d", &n);
    for(int i = 0 ; i < n ; i++)
        cin >> a[i];
    printf("%.15f\n",Search());
    return 0;
}

 

posted @ 2017-08-27 17:27  pprp  阅读(343)  评论(0编辑  收藏  举报