P9525 [JOISC2022] 团队竞技 题解

题意:

给定 nn 个三元组 (ai,bi,ci)(a_i,b_i,c_i),求 1i,j,kn1\leq i,j,k \leq ni,j,ki,j,k 互不相等,满足 ai>max{aj,ak},bj>max{bi,bk},ck>max{ci,cj}a_i > \max\{a_j,a_k\}, b_j > \max\{b_i,b_k\}, c_k > \max \{c_i, c_j\},最大化 ai+bj+cka_i + b_j + c_k

考虑如果没有 ai>max{aj,ak},bj>max{bi,bk},ck>max{ci,cj}a_i > \max\{a_j,a_k\}, b_j > \max\{b_i,b_k\}, c_k > \max \{c_i, c_j\} 的限制,我们显然分别取 a,b,ca,b,c 最大的三个。然而直接取这三个可能会违反这个限制。

具体的,i,j,ki,j,k 中必然有一个 a,b,ca,b,c 中有大于等于 22 个值都是 i,j,ki,j,k 中最大的。比如对于 iiai>max{aj,ak},bi>max{bj,bk}a_i > \max\{a_j,a_k\}, b_i > \max\{b_j,b_k\}。此时 jj 已经选到了 bb 的最大值,故怎么选,都有 bi>bjb_i > b_j。于是只要选了 ii,就无法选出这一组 (i,j,k)(i,j,k)。接着把 ii 删了,递归成一个 n1n-1 的子问题。维护 priority_queue 即可。

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 5;

int n;
struct Node
{
	int a, b, c;
	Node(int a, int b, int c): a(a), b(b), c(c){}
	Node(){}
}p[N];

bool del[N];

int main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> p[i].a >> p[i].b >> p[i].c;
	}
	priority_queue<pair<int, int>> p1, p2, p3;
	for (int i = 1; i <= n; i++)
	{
		p1.push(make_pair(p[i].a, i));
		p2.push(make_pair(p[i].b, i));
		p3.push(make_pair(p[i].c, i));
	}
	for (int i = 1; i <= n; i++)
	{
		while (p1.size() && del[p1.top().second]) p1.pop();
		while (p2.size() && del[p2.top().second]) p2.pop();
		while (p3.size() && del[p3.top().second]) p3.pop();
		vector<pair<int, Node>> vv;
		vv.emplace_back(make_pair(p1.top().second, p[p1.top().second]));
		vv.emplace_back(make_pair(p2.top().second, p[p2.top().second]));
		vv.emplace_back(make_pair(p3.top().second, p[p3.top().second]));
		//cout << i << " " << p1.top().second << " " << p2.top().second << " " << p3.top().second << "\n";  
		for (int j = 0; j < 3; j++)
		{
			int c = 0;
			bool fg = 1;
			for (int k = 0; k < 3; k++)
			{
				if (j == k) continue;
				fg &= (vv[j].second.a >= vv[k].second.a);
			}
			c += fg;
			fg = 1;
			for (int k = 0; k < 3; k++)
			{
				if (j == k) continue;
				fg &= (vv[j].second.b >= vv[k].second.b);
			}
			c += fg;
			fg = 1;
			for (int k = 0; k < 3; k++)
			{
				if (j == k) continue;
				fg &= (vv[j].second.c >= vv[k].second.c);
			}
			c += fg;
			if (c >= 2)
			{
				del[vv[j].first] = 1;
				goto E;
			}
		}
		cout << max({vv[0].second.a, vv[1].second.a, vv[2].second.a}) + max({vv[0].second.b, vv[1].second.b, vv[2].second.b}) + max({vv[0].second.c, vv[1].second.c, vv[2].second.c}) << "\n";
		return 0;
		E:;
	}
	cout << "-1\n";
	return 0;
}
posted @   HappyBobb  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示