码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 578c - weekness and poorness - 三分

时间:2017-08-28 00:55:06      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:color   else   ret   date   序列   ogr   force   can   tmp   

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;
}

 

codeforces 578c - weekness and poorness - 三分

标签:color   else   ret   date   序列   ogr   force   can   tmp   

原文地址:http://www.cnblogs.com/pprp/p/7440904.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!