P6346 [CCO2017] 专业网络 紫 题解

从 CF1251E1 来的,补一发。

原题链接

思路

一眼丁真,鉴定为 \(O(n \log_2 n)\) 贪心。

首先将所有人按 \(a_i\) 从小到大的顺序排序,再倒序循环枚举每个人,使得有更高代价的人可以被“零元购”就成为 Kevin 的朋友 。每次将排完序后的第 \(i\) 个人的 \(b_i\) 值存入小根堆,如果这个人的 \(a_i\) 大于可“零元购”成为 Kevin 的朋友的人数 \(n-size\),则将所求答案 \(ans\) 加上堆顶元素,然后弹出堆顶,视作已成为 Kevin 的朋友。最后输出答案 \(ans\)

有不懂看代码。

代码(有注释)

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

int n;//人数
struct node {
	int a,b;
	bool operator < (const node &x) const {
		return a<x.a;
	}//重载运算符
} a[200010];//人
priority_queue<int,vector<int>,greater<int> > h;//定义小根堆

signed main () {
	cin>> n;
	long long ans=0;//让所有人成为 Kevin 的朋友的最小代价
	for (int i=1;i<=n;i++)
		cin>> a[i].a>> a[i].b;//输入人
	sort (a+1,a+n+1);//按ai排序
	for (int i=n;i>=1;i--) {//逆序枚举
		h.push (a[i].b);//压入堆
		if (a[i].a>n-h.size ()) {//判断是否不符合条件
			ans+=h.top ();//增加花销
			h.pop ();//弹出
		}
	}
	cout<< ans;//输出
	return 0;//圆满结束
}
posted @ 2025-03-04 20:40  M_CI  阅读(18)  评论(0)    收藏  举报