最大和(前缀和)

题目描述

给你一个数组a1,a2,...,an,其中所有元素都是不同的。

你必须对其进行k次操作。在每个操作中,你需要做以下两个操作中的一个(每次任选其中之一即可):

1.找到数组中的两个最小元素,并删除它们;
2.找到数组中的最大元素,并删除它。

计算出k次操作后,所得数组的最大元素之和。

输入描述

第一行包含一个整数 t (1≤t≤104) — 测试用例的数量。

每个测试用例由两行组成:
第一行包含两个整数 n和 k (3≤n≤2⋅10^5; 1≤k≤99999; 2k<n) — 元素和操作的数量。
第二行包含n个整数 a1,a2,...,an (1≤ai≤10^9;所有 ai不同) — 数组的元素。

数据保证n的总和不超过2⋅105。

输出描述

对于每个测试用例,输出一个整数 — 结果数组中元素的最大可能总和。

输入样例

6
5 1
2 5 1 10 6
5 2
2 5 1 10 6
3 1
1 2 3
6 1
15 22 12 10 13 11
6 2
15 22 12 10 13 11
5 1
999999996 999999999 999999997 999999998 999999995

输出样例

21
11
3
62
46
3999999986

样例解释

在第一个测试用例中,使用第一个操作会产生以下结果:

*两个最小值为 1和 2;删除它们会使数组保留为 [5,10,6],总和为 21;

*最大值为 10;删除它会使数组保留为 [2,5,1,6],总和为 14.

很明显,21是最好的答案。

在第二个测试用例中,最优选择是一次删除两个最小值,一次删除最大值,这样就能得到11。

解题思路

对于这道题,我们首先想到的是对操作次数k依次枚举,我们可以执行操作1从0开始枚举,则操作2从k开始枚举,由此算出删除数总和的最小值,我们用总和减去删除数的和的最小值即最终答案。由数据范围知,k最大为99999,则枚举后时间复杂度为O(k^2),显然会直接暴错,所以我们要对代码进行优化。这里在求和的过程中我们可以利用前缀和来进行求解。如下图所示:(以倒数第二个样例为例)

最终代码:

#include <iostream>
#include <algorithm>
using namespace std;
const int N=2e5+10;
long long a[N];
long long ans,sum;//ans代表删除数总和
int main()
{
    int T;
    cin >> T;
    while(T--)
    {
    int n,k;
    cin >> n >> k;//n代表数组元素的个数,k代表操作次数
    sum=0;//计算每组数据和之前将总和初始化为0
    for(int i=1;i<=n;i++)
    {
        cin >> a[i];
        sum+=a[i];
    }
    sort(a+1,a+1+n);//将数组元素排序
    for(int i=1;i<=n;i++)
    {
        a[i]+=a[i-1];//计算前缀和数组
    }
    ans=1e20;//计算删除和的最小值,将ans初始化为最大
    int t=0;
    for(int i=0;i<=k;i++)
    {
        if(ans>a[t]+a[n]-a[n-k+i])
        {
            ans=a[t]+a[n]-a[n-k+i];
            //a[t]代表删除最小值的和
            //n-(k-i)代表删除最小值后剩下的操作数
            //a[n]-a[n-k+i]代表删除最大值的和
        }
        t+=2;
    }
    cout << sum-ans<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值