【AtCoder】 Grand Contest 018 C - Coins

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

  • 1X
  • 1Y
  • 1Z
  • X+Y+Z105
  • 1Ai109
  • 1Bi109
  • 1Ci109

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

Copy
1 2 1
2 4 4
3 2 1
7 6 7
5 2 3

Sample Output 1

Copy
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

Copy
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

Copy
110

Sample Input 3

Copy
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

Copy
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;
}



AtCoder Practice Contest #B - インタラクティブ練習 (Interactive Sorting) 是一道比较有趣的题目。它是一道交互式的排序题目,需要你与一个神秘程序进行交互,以便将一串无序的数字序列排序。 具体来说,这个神秘程序会给你一个长度为 $N$ 的数字序列,然后你需要通过询问它两个数字的大小关系,来逐步确定这个序列的排序顺序。每次询问之后,神秘程序都会告诉你两个数字的大小关系,比如第一个数字比第二个数字小,或者第二个数字比第一个数字小。你需要根据这个信息,来调整这个数字序列的顺序,然后再向神秘程序询问下一对数字的大小关系,以此类推,直到这个数字序列被完全排序为止。 在这个过程中,你需要注意以下几点: 1. 你最多只能向神秘程序询问 $Q$ 次。如果超过了这个次数,那么你的程序会被判定为错误。 2. 在每次询问之后,你需要及时更新数字序列的顺序。具体来说,如果神秘程序告诉你第 $i$ 个数字比第 $j$ 个数字小,那么你需要将这两个数字交换位置,以确保数字序列的顺序是正确的。如果你没有及时更新数字序列的顺序,那么你的程序也会被判定为错误。 3. 在询问的过程中,你需要注意避免重复询问。具体来说,如果你已经询问过第 $i$ 个数字和第 $j$ 个数字的大小关系了,那么你就不需要再次询问第 $j$ 个数字和第 $i$ 个数字的大小关系,因为它们的大小关系已经被确定了。 4. 在排序完成之后,你需要将排序结果按照从小到大的顺序输出。如果你输出的结果不正确,那么你的程序也会被判定为错误。 总的来说,这道题目需要你熟练掌握交互式程序设计的技巧,以及排序算法的实现方法。如果你能够熟练掌握这些技巧,那么就可以顺利地完成这道非传统题了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值