【16级第二周寒假作业A题】

探讨如何通过选择合适的实数x使给定整数序列的脆弱度达到最小,介绍使用三分法寻找最优解的过程。

网址链接:http://210.34.193.66:8080/vj/Contest.jsp?cid=161#P0

Weakness and Poorness

TimeLimit: 2000ms  MemoryLimit:262144KB
64-bit integer IO format: %I64d
Problem Description

You are given a sequence of n integers a1, a2, ..., an.

Determine a real number x such that the weakness of the sequence a1 - x, a2 - x, ..., an - x is as small as possible.

The weakness of a sequence is defined as the maximum value of the poorness over all segments (contiguous subsequences) of a sequence.

The poorness of a segment is defined as the absolute value of sum of the elements of segment.

给出一个n个整数a1,a2,...,an的序列。

求实数x使得新序列a1-x,a2-x,...,an-x的脆弱度尽可能小。

序列的脆弱度定义为序列的所有片段(连续子序列)上的不良性的最大值。

子序列的不良度被定义为子序列的元素的和的绝对值。

Input

The first line contains one integer n (1 ≤ n ≤ 200 000), the length of a sequence.

The second line contains n integers a1, a2, ..., an (|ai| ≤ 10 000).

Output

Output a real number denoting the minimum possible weakness of a1 - x, a2 - x, ..., an - x. Your answer will be considered correct if its relative or absolute error doesn't exceed 10 - 6.

SampleInput 1
3
1 2 3
SampleOutput 1
1.000000000000000
SampleInput 2
4
1 2 3 4
SampleOutput 2
2.000000000000000
SampleInput 3
10
1 10 2 9 3 8 4 7 5 6
SampleOutput 3
4.500000000000000
Note
For the first case, the optimal value of x is 2 so the sequence becomes  - 1, 0, 1 and the max poorness occurs at the segment "-1" or segment "1". The poorness value (answer) equals to 1 in this case.

For the second sample the optimal value of x is 2.5 so the sequence becomes  - 1.5,  - 0.5, 0.5, 1.5 and the max poorness occurs on segment "-1.5 -0.5" or "0.5 1.5". The poorness value (answer) equals to 2 in this case.



思路:

题目的专有名词再加上题意的模棱两可可能会让一些人蒙蔽。。大意就是:给出一个数组a,计算出新数组a[1]-x,a[2]-x,a[3]-x……的连续子序列元素的和(也就是区间和)的绝对值的最大值。而因为x值得不同,这个绝对值也会不同,这里我们要的最终结果就是:所有可能的绝对值的最小值!

连续子序列元素和的绝对值的最大值,根据上周作业的前缀和知识,我们很容易就能知道用max(sum[j])-min(sum[i])求得。

至于x的值,我们可以利用三分法来确定。三分法可用于求有数学函数关系的最小值问题。【算法讲解】三分法: http://www.cnblogs.com/syiml/p/3675214.html

/*
*区间和函数
*/
double f(double x)
{
	int i;
	double sum[200005]={0},max=0,min=0;//令max=min=sum[0]=0.
	for(i=1;i<=n;i++)
	{
		sum[i]=sum[i-1]+a[i-1]-x;
		if(max<sum[i])max=sum[i];
		if(min>sum[i])min=sum[i];
	}
	return max-min;
}
/*
*三分法
*/
double l=-1e9,m,mm,r=1e9;
for(i=0;i<200;i++)//因为这里输出答案精度精确到15位,用固定次数循环比较方便。。100精度还不行,200亲测足矣!
{
	m=l+(r-l)/3;//m,mm三等分。也可以m=(l+r)/2;
	mm=r-(r-l)/3;//也可以mm=(m+r)/2;
	if(f(m)<f(mm))r=mm;
	else
		l=m;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值