[AGC018C] Coins 题解

先全部选 \(a_i\),假设 \(b_i=b_i-a_i,c_i=c_i-a_i\)

那么题目转化为选 \(y\)\(b\)\(z\)\(c\) 使得答案最大。

会发现若 \(i\) 位置选的 \(b\)\(j\) 位置选的 \(c\),那么需要满足 \(b_i-c_i>b_j-c_j\)

我们按上述条件排序,这样一定是在左边选 \(b\),右边选 \(c\)

那么题目又简化为给定数组 \(b\),在前 \(i\) 个里面选出 \(y\) 个数的最大和,直接反悔贪心即可。

//dzzfjldyqqwsxdhrdhcyxll
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 1e5 + 10;
int x,y,z,n,sum,f[MAXN],g[MAXN],ans = -1e18;
struct Node {
	int a,b,c;
}q[MAXN];
inline bool cmp(Node x,Node y) {
	return x.b - x.c > y.b - y.c;
} 
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> x >> y >> z;
	n = x + y + z; 
	for(int i = 1;i <= n;i++) {
		cin >> q[i].a >> q[i].b >> q[i].c;
		sum += q[i].a;
		q[i].b -= q[i].a;
		q[i].c -= q[i].a;
	}
	sort(q + 1,q + n + 1,cmp);
	priority_queue <int,vector <int>,greater <int> > Q; 
	for(int i = 1;i <= n;i++) {
		if(Q.size() < y) {
			f[i] = f[i - 1] + q[i].b;
			Q.push(q[i].b);
		} else {
			f[i] = f[i - 1];
			if(Q.top() < q[i].b) {
				f[i] += q[i].b - Q.top();
				Q.pop();
				Q.push(q[i].b);
			}
		}
	}
	while(!Q.empty()) Q.pop();
	for(int i = n;i >= 1;i--) {
		if(Q.size() < z) {
			g[i] = g[i + 1] + q[i].c;
			Q.push(q[i].c);
		} else {
			g[i] = g[i + 1];
			if(Q.top() < q[i].c) {
				g[i] += q[i].c - Q.top();
				Q.pop();
				Q.push(q[i].c);
			}
		}
	}
	for(int i = y;i <= n - z;i++) {
		ans = max(ans,f[i] + g[i + 1]);	
	}
	cout << ans + sum;
	return 0;
} 
posted @ 2024-11-16 16:14  Creeper_l  阅读(33)  评论(0)    收藏  举报