#前缀和
问题描述
小明是一名勇敢的冒险家,他在一次探险途中发现了一组神秘的宝石,这些宝石的价值都不同。但是,他发现这些宝石会随着时间的推移逐渐失去价值,因此他必须在规定的次数内对它们进行处理。
小明想要最大化这些宝石的总价值。他有两种处理方式:
- 选出两个最小的宝石,并将它们从宝石组中删除。
- 选出最大的宝石,并将其从宝石组中删除。 现在,给你小明手上的宝石组,请你告诉他在规定的次数内,最大化宝石的总价值是多少。
-
输入格式
第一行包含一个整数 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用于存放操作后宝石的总价值。