最大数组和(Lanqiao OJ 3260)

#前缀和


问题描述

小明是一名勇敢的冒险家,他在一次探险途中发现了一组神秘的宝石,这些宝石的价值都不同。但是,他发现这些宝石会随着时间的推移逐渐失去价值,因此他必须在规定的次数内对它们进行处理。

小明想要最大化这些宝石的总价值。他有两种处理方式:

  1. 选出两个最小的宝石,并将它们从宝石组中删除。
  2. 选出最大的宝石,并将其从宝石组中删除。                                                                                                                                                                                                                                                                            现在,给你小明手上的宝石组,请你告诉他在规定的次数内,最大化宝石的总价值是多少。

    • 输入格式

      第一行包含一个整数  t,表示数据组数。

      对于每组数据,第一行包含两个整数  n 和 k ,表示宝石的数量和规定的处理次数。第二行包含 n 个整数 a1,a2,...,an,表示每个宝石的价值。


      输出格式

对于每组数据,输出一个整数,表示在规定的次数内,最大化宝石的总价值。


样例输入

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

题解:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 2e5 + 9;
ll a[N];
ll pre[N];


int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	while (t--) {
		int n, k;
		cin >> n >> k;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];

		}
		sort(a + 1, a + n + 1);
		for (int i = 1; i <= n; i++) {
			pre[i] = pre[i - 1] + a[i];
		}

		ll ans = 0;
		ll x;
		for (int i = 0; i <= k; i++) {
			x = pre[n - (k - i)] - pre[2 * i];
			ans =	max(ans, x);
		}



		cout <<	ans << endl;
	}




	return 0;
}


总结:

定义一个数组 a[N] 用于存放这一组宝石。

sort(a+1,a+n+1)对这一组宝石由小到大进行排序。

计算其前缀和 pre[i] .pre[i] = pre[i - 1] + a[i];

定义一个x用于存放操作后宝石的总价值。

for (int i = 0; i <= k; i++) {
            x = pre[n - (k - i)] - pre[2 * i];
            ans =    max(ans, x);
        }

pre[n-(k-i)] - pre[2*i]表示选择了k-i个最大元素操作,和2*i个最小元素操作后的宝石价值和。(一共删除操作数为k次,删除i次最小元素,那么就删除 k - i次 最大元素)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值