题目链接 Hrbust 2319
首先把二元组排序,$ai$大的排前面,$ai$相同的$bi$大的排前面。
这样的话就满足了Kim的取数顺序,即选每次$ai$最大的。
考虑得坏一些,在$ai$相同的时候每次选&bi&最大的。
我们从第$2$个位置开始考虑,默认选排名为偶数的,并且一个个把取到的$bi$放进优先队列(小根堆)
当位置标号为奇数并且堆顶元素小于当前的$bi$的时候把堆顶元素弹出来并且把这个$bi$放进去。
其意义为放弃前面标号为偶数点$bi$小的,抓这个编号为奇数并且$bi$大的。
根据Kim的贪婪准则他肯定会去选前面被我们放弃的东西,所以可保证我们得到的$bi$和最大。
最后优先队列里面的元素和即为答案。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const int N = 1010; struct node{ LL x, y; friend bool operator < (const node &a, const node &b){ return a.x == b.x ? a.y > b.y : a.x > b.x; } } a[N]; priority_queue <LL, vector <LL>, greater<LL> > q; int T; int n; LL ans; int main(){ scanf("%d", &T); while (T--){ scanf("%d", &n); rep(i, 1, n) scanf("%lld", &a[i].x); rep(i, 1, n) scanf("%lld", &a[i].y); sort(a + 1, a + n + 1); rep(i, 2, n) if (i % 2 == 0){ q.push(a[i].y); } else if (q.top() < a[i].y){ q.pop(); q.push(a[i].y); } ans = 0; while (!q.empty()) ans += q.top(), q.pop(); printf("%lld\n", ans); } return 0; }