CF1251E1 Voting (Easy Version) 蓝 题解

原题链接

思路

一眼丁真,鉴定为贪心。

一开始想了个 O ( t × n 2 ) O(t \times n^2) O(t×n2) 的暴力贪心,但因为看错数据范围而打了个 O ( t × n log ⁡ 2 n ) O(t \times n \log_2 n) O(t×nlog2n) 的小根堆维护的贪心。

首先将所有人按 m i m_i mi 从小到大的顺序排序,再倒序循环枚举每个人,使得有更高金钱需求的人可以被“零元购”就获得支持。每次将排完序后的第 i i i 个人的 q i q_i qi 值存入小根堆,如果这个人的 m i m_i mi 大于可“零元购”获得支持的人数 n − s i z e n-size nsize,则将所求答案 a n s ans ans 加上堆顶元素,然后弹出堆顶,视作已获得其支持。最后输出答案 a n s ans ans

如果不懂看代码。

代码(有注释)

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

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

signed main () {
	cin>> t;//输入数据组数
	while (t--) {
		cin>> n;
		long long ans=0;//所求答案(即最小代价)
		while (h.size ()) h.pop ();//多测记得清空
		for (int i=1;i<=n;i++)
			cin>> a[i].m>> a[i].q;//输入人
		sort (a+1,a+n+1);//按mi排序
		for (int i=n;i>=1;i--) {//逆序枚举
			h.push (a[i].q);//压入堆
			if (a[i].m>n-h.size ()) {//判断是否不符合条件
				ans+=h.top ();//增加花销
				h.pop ();//弹出
			}
		}
		cout<< ans<< "\n";//输出
	}
	return 0;//圆满结束
}

马蜂不好,勿喷

据说多倍经验,写一下:

CF1251E2

P6346

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值