C - Coins
Time limit : 2sec / Memory limit : 256MB
Score : 800 points
Problem Statement
There are X+Y+Z people, conveniently numbered 1 through X+Y+Z. Person i has Ai gold coins, Bi silver coins and Ci bronze coins.
Snuke is thinking of getting gold coins from X of those people, silver coins from Y of the people and bronze coins from Z of the people. It is not possible to get two or more different colors of coins from a single person. On the other hand, a person will give all of his/her coins of the color specified by Snuke.
Snuke would like to maximize the total number of coins of all colors he gets. Find the maximum possible number of coins.
Constraints
- 1≤X
- 1≤Y
- 1≤Z
- X+Y+Z≤105
- 1≤Ai≤109
- 1≤Bi≤109
- 1≤Ci≤109
Input
Input is given from Standard Input in the following format:
X Y Z A1 B1 C1 A2 B2 C2 : AX+Y+Z BX+Y+Z CX+Y+Z
Output
Print the maximum possible total number of coins of all colors he gets.
Sample Input 1
1 2 1 2 4 4 3 2 1 7 6 7 5 2 3
Sample Output 1
18
Get silver coins from Person 1, silver coins from Person 2, bronze coins from Person 3 and gold coins from Person 4. In this case, the total number of coins will be 4+2+7+5=18. It is not possible to get 19 or more coins, and the answer is therefore 18.
Sample Input 2
3 3 2 16 17 1 2 7 5 2 16 12 17 7 7 13 2 10 12 18 3 16 15 19 5 6 2
Sample Output 2
110
Sample Input 3
6 2 4 33189 87907 277349742 71616 46764 575306520 8801 53151 327161251 58589 4337 796697686 66854 17565 289910583 50598 35195 478112689 13919 88414 103962455 7953 69657 699253752 44255 98144 468443709 2332 42580 752437097 39752 19060 845062869 60126 74101 382963164
Sample Output 3
3093929975
题目链接:http://agc018.contest.atcoder.jp/tasks/agc018_c
题目大意: 有x+y+z个人, 每个人有a[i] 个金币 b[i] 个银币, c[i]个铜币, 从n个人里面选x个人拿金, y个人拿银, z个人拿铜,所能拿到的最大金币个数是多少。
解题思路: 对于这道题我们可以先想一个简化版本的: x+y个人只有金币和银币, 那么我们按照a[i] - b[i] 从小到大排序, 那么银币肯定从左边的y个选, 金币从右边的x个选, 这样才拿的肯定是最大的。
对于x+y+z个人来说, 按照a[i] - b[i] 从小到大排序之后, 那么银币肯定从左边的k个选, 金币从右边n-k张牌里选, 所以可以枚举一个k, 用优先队列维护金币值, 对于c n个人选完x和y后, 剩下的就是选c的, 可以不用考虑, 最后直接加进去c的值就可以。
//2017-7-28 21:13
//2017-7-28 21:38
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std;
typedef long long LL;
const int MaxN = 1e5;
struct node{
LL a, b, c;
bool operator <(const node &A) const{
return (a-b) < A.a - A.b;
}
}box[MaxN + 5];
int n, x, y, z;
LL tot, ans;
priority_queue<LL, vector<LL>, greater<LL> > q;
LL lef[MaxN + 5];
int main(){
scanf("%d %d %d", &x, &y, &z);
n = x + y + z;
for(int i = 1; i <= n; i++){
scanf("%lld %lld %lld", &box[i].a, &box[i].b, &box[i].c);
tot += box[i].c;
}
sort(box + 1, box + 1 + n);
LL ans = 0, sum = 0;
for(int i = 1; i <= y; i++){
sum += box[i].b - box[i].c;
q.push(box[i].b - box[i].c);
}
for(int i = y + 1; i <= n - x + 1; i++){
lef[i] = sum;
sum += box[i].b - box[i].c;
q.push(box[i].b - box[i].c);
sum -= q.top();
q.pop();
}
while(!q.empty()) q.pop(); sum = 0;
for(int i = n; i > n - x; i--){
sum += box[i].a - box[i].c;
q.push(box[i].a - box[i].c);
}
for(int i = n - x; i >= y; i--){
ans = max(ans, tot + lef[i + 1] + sum);
sum += box[i].a - box[i].c;
q.push(box[i].a - box[i].c);
sum -= q.top();
q.pop();
}
printf("%lld\n", ans);
return 0;
}