数列的划分

数列划分

一、题目

内容描述

一个长度为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}(2n105,105ai105,1in,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},1kn1. 现在将 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=nk+11i=knaink1i=k+1nai=(nk+1)(nk)1i=k+1nai+(nk+1)(nk)(nk)ak=(nk+1)(nk)1[(nk)aki=k+1nai]0.
上式中 a k ≤ a i ( k + 1 ≤ i ≤ n ) a_k \leq a_i(k+1 \leq i \leq n) akai(k+1in).

故得:不断将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=k11i=1k1aik1i=1kai=k(k1)1i=1k1aikak=k(k1)1[i=1k1ai(k1)ak]0.
上式中 a i ≤ a k ( 1 ≤ i ≤ k − 1 ) a_i \leq a_k(1 \leq i \leq k-1) aiak(1ik1).

故得:不断将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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GaspardR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值