数列划分
一、题目
内容描述
一个长度为n的数列a,其中的元素有正有负,将原数列分成两个子数列A,B,同时让两个数列的平均值之和最大。输出划分好的两个数列的平均值之和,保留两位小数。
输入
第一行一个正整数n,表示数列长度。
接下来一行,每行n个整数,表示给出的数列。
输出
输出一个浮点数,保留两位小数,表示所有划分方案中,两个数列平均值之和的最大值。
样例
\quad 输入:
3
1 3 2
\quad 输出:
4.50
二、分析
结论
一个子数列包含数列的一个最大值,另一个子数列包含剩余数列的值。
证明
现有升序数列
{
a
n
}
(
2
≤
n
≤
1
0
5
,
−
1
0
5
≤
a
i
≤
1
0
5
,
1
≤
i
≤
n
,
a
1
最
小
,
a
n
最
大
)
\{a_n\}(2 \leq n \leq 10^5, -10^5 \leq a_i \leq 10^5, 1 \leq i \leq n,a_1最小,a_n最大)
{an}(2≤n≤105,−105≤ai≤105,1≤i≤n,a1最小,an最大),设子数列
A
=
{
a
k
+
1
,
⋯
,
a
n
}
,
B
=
{
a
1
,
a
2
,
⋯
,
a
k
}
,
1
≤
k
≤
n
−
1
A = \{a_{k+1}, \cdots, a_n\}, B = \{a_1, a_2, \cdots ,a_{k}\}, 1 \leq k \leq n-1
A={ak+1,⋯,an},B={a1,a2,⋯,ak},1≤k≤n−1. 现在将
B
B
B中最大值
a
k
a_k
ak移入
A
A
A,则
Δ
A
‾
=
1
n
−
k
+
1
∑
i
=
k
n
a
i
−
1
n
−
k
∑
i
=
k
+
1
n
a
i
=
−
1
(
n
−
k
+
1
)
(
n
−
k
)
∑
i
=
k
+
1
n
a
i
+
(
n
−
k
)
a
k
(
n
−
k
+
1
)
(
n
−
k
)
=
1
(
n
−
k
+
1
)
(
n
−
k
)
[
(
n
−
k
)
a
k
−
∑
i
=
k
+
1
n
a
i
]
≤
0.
\Delta \overline A =\dfrac {1}{n-k+1}\sum_{i=k}^na_i - \dfrac {1}{n-k}\sum_{i=k+1}^na_i \\= \dfrac {-1}{(n-k+1)(n-k)}\sum_{i=k+1}^na_i + \dfrac {(n-k)a_k}{(n-k+1)(n-k)} \\= \dfrac{1}{(n-k+1)(n-k)}[(n-k)a_k - \sum_{i=k+1}^na_i] \leq 0. \quad \quad
ΔA=n−k+11i=k∑nai−n−k1i=k+1∑nai=(n−k+1)(n−k)−1i=k+1∑nai+(n−k+1)(n−k)(n−k)ak=(n−k+1)(n−k)1[(n−k)ak−i=k+1∑nai]≤0.
上式中
a
k
≤
a
i
(
k
+
1
≤
i
≤
n
)
a_k \leq a_i(k+1 \leq i \leq n)
ak≤ai(k+1≤i≤n).
故得:不断将B中最大值移入A中时,
A
‾
\overline A
A减小. 同理有
Δ
B
‾
=
1
k
−
1
∑
i
=
1
k
−
1
a
i
−
1
k
∑
i
=
1
k
a
i
=
1
k
(
k
−
1
)
∑
i
=
1
k
−
1
a
i
−
a
k
k
=
1
k
(
k
−
1
)
[
∑
i
=
1
k
−
1
a
i
−
(
k
−
1
)
a
k
]
≤
0.
\Delta \overline B = \dfrac{1}{k-1}\sum_{i=1}^{k-1}a_i - \dfrac{1}{k}\sum_{i=1}^{k}a_i \\= \dfrac{1}{k(k-1)}\sum_{i=1}^{k-1}a_i - \dfrac{a_k}{k}\qquad\qquad\quad\\ = \dfrac{1}{k(k-1)}[\sum_{i=1}^{k-1}a_i - (k-1)a_k] \leq 0.
ΔB=k−11i=1∑k−1ai−k1i=1∑kai=k(k−1)1i=1∑k−1ai−kak=k(k−1)1[i=1∑k−1ai−(k−1)ak]≤0.
上式中
a
i
≤
a
k
(
1
≤
i
≤
k
−
1
)
a_i \leq a_k(1 \leq i \leq k-1)
ai≤ak(1≤i≤k−1).
故得:不断将B中最大值移入A中时, B ‾ \overline{B} B减小.
又A不能为空集,综上可得:A中有且仅有一个最大值时, A ‾ + B ‾ \overline A + \overline B A+B最大.
三、时间复杂度
排序所花费的时间 Θ ( n l g n ) \Theta (nlgn) Θ(nlgn).
四、c实现
#include <stdio.h>
#define MAXLEN 100000
int a[MAXLEN];
int main()
{
int n, max = -10000000;
long long int sum = 0;
scanf("%d", &n);
int i;
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
sum += a[i];
if (max < a[i]) max = a[i];
}
printf("%.2f", 1.0*(sum-max)/(n-1) + max);
return 0;
}