站外题求助
给定一个包含N个整数的数组。请从数组中选出M组有序数对 。
每组有序数对由数组中的 两个元素组成,且每组有序数对 只能用一次。请编程计算出,在给定的数组中,选出的 M组 有序数对的和的最大值是多少。
本题中的有序数对,指的是符合如下两个条件 其中之一数对: 从N个数中,选出两个不同位置的整数。比如第 i个数Ai和第 j个数Aj( i≠j),则Ai,Aj和Aj,Ai 为两组不同的有序数对。
- 从N个数中,选出同一个位置的整数2 次,组成一组有序数对。比如第i个数Ai,Ai 即构成一组有序数对。 输入 第一行包含两个整数 N和M ,分别表示数组中元素的个数和需要选择的有序数对数量。
- (34,34) ,和为34+34=68 ;
- (34,33) ,和为 34+33=67 ;
- (33,34) ,和为33+34=67; 总和为68+67+67=202。
第二行包含 N个整数 A1,A2,...,AN ,表示数组中的每个元素的值。 输出 输出一个整数,表示选出的 M个有序数对的和的最大值。 样例 输入
5 3 34 33 10 14 19
输出
202
输入
9 14 110 24 21 34 1 3 5 5 3
输出
1837
输入
9 73 64141 40773 79105 16076 67597 52981 5828 66249 75177
输出
8128170
34,33,10,14,19,需要选3个有序数对。
一种可能的方案:
数据范围
对于 15% 的数据,满足所有的 Ai 全部相同。
对于50%的数据,满足1≤N≤100 。
对于100%的数据,满足 1≤N≤10^5,1≤M≤N^2 , 1≤Ai≤10^5 。
#include <bits/stdc++.h>
using namespace std;
struct Node{
long long sum;
int i;
int j;
Node(long long s, int i_, int j_) : sum(s), i(i_), j(j_) {}
bool operator<(const Node& other) const {
return sum < other.sum;
}
};
int main() {
int n, m;
cin >> n >> m;
vector<long long> A(n);
for (int i = 0; i < n; ++i) {
cin >> A[i];
}
sort(A.rbegin(), A.rend());
priority_queue<Node> pq;
unordered_set<long long> vis;
if (n >= 1) {
long long tmp = 0LL * (n + 1) + 0;
vis.insert(tmp);
pq.emplace(A[0] + A[0], 0, 0);
}
if (n >= 2) {
long long tmp = 0LL * (n + 1) + 1;
vis.insert(tmp);
pq.emplace(A[0] + A[1], 0, 1);
}
long long ans = 0;
int remaining = m;
while (remaining > 0 && !pq.empty()) {
Node node = pq.top();
pq.pop();
long long s = node.sum;
int i = node.i;
int j = node.j;
int count = (i == j) ? 1 : 2;
int take = min(count, remaining);
ans += take * s;
remaining -= take;
if (remaining == 0) {
break;
}
if (i == j) {
int ni = i + 1;
int nj = j + 1;
if (ni < n && nj < n) {
long long tmp = 1LL * ni * (n + 1) + nj;
if (!vis.count(tmp)) {
vis.insert(tmp);
pq.emplace(A[ni] + A[nj], ni, nj);
}
}
} else {
int nj = j + 1;
if (nj < n) {
long long tmp = 1LL * i * (n + 1) + nj;
if (!vis.count(tmp)) {
vis.insert(tmp);
pq.emplace(A[i] + A[nj], i, nj);
}
}
int ni = i + 1;
if (ni < j) {
long long tmp = 1LL * ni * (n + 1) + j;
if (!vis.count(tmp)) {
vis.insert(tmp);
pq.emplace(A[ni] + A[j], ni, j);
}
}
}
}
cout << ans;
return 0;
}
有没有大佬给个思路或调一下代码

查看14道真题和解析