先全部选 \(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\) 个里面选出 \(z\) 个数的最大和,直接反悔贪心即可。
//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;
}