ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[NJUPSOJ]"996"

2021-02-17 11:33:55  阅读:139  来源: 互联网

标签:cnt 996 int ++ NJUPSOJ pq ans include


discription:
给定\(n\)项工作的起止时间, 每个工人同一时间最多干一件工作. 问做完这些工作最少要雇佣多少工人?(万恶的资本家)
\(第一行一个整数 n,(1≤n≤100000),表示工作的数目.\)
\(接下来 n 行, 第 i+1 行有俩整数 S_i, E_i, (0≤Si<Ei≤10000000000).\)
solution:
1:有贪心性质, 按照开始时间对这\(n\)件工作排序.
2.维护一个优先队列(小根堆), 堆顶记录当前的最小区间右值.
优先队列的用法:

#include<queue>
using namespace std;

最大堆:priority_queue<int>
最小堆:priority_queue<int, vector<int>, greater<int> >
code:

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 1e6;
struct range {
	int l, r;
}a[N];
bool operator < (range& a, range& b) {
	return a.l < b.l;
}
priority_queue<int, vector<int>, greater<int> >pq;
int main() {
	int n; scanf("%d", &n);
	for (int i = 0; i < n; ++i)scanf("%d%d", &a[i].l, &a[i].r);
	sort(a, a + n);
	int ans = 1;
	pq.push(a[0].r);
	for (int i = 1; i < n; ++i) {
		if (a[i].l < pq.top()) {
			pq.push(a[i].r);
			++ans;
		}
		else {
			pq.pop();
			pq.push(a[i].r);
		}
	}
	printf("%d\n", ans);
}

另解: 我看到一种神奇的解法:
对区间左值与右值分别排序, 代码极其简洁. 在纸上模拟一下好像是这样, 但是它的正确性该怎么理解呢 ?

#include<cstdio>
#include<algorithm>
const int N = 1e6;
int l[N], r[N], n;
int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)scanf("%d%d", l + i, r + i);
	int i(0), j(0), cnt(0), ans(0);
	std::sort(l, l + n);
	std::sort(r, r + n);
	while (i < n && j < n) {
		if (l[i] < r[j])++i, ++cnt, ans < cnt ? ans = cnt : 0;
		else ++j, --cnt;
	}
	printf("%d\n", ans);
}

标签:cnt,996,int,++,NJUPSOJ,pq,ans,include
来源: https://www.cnblogs.com/dwt2021/p/14408466.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有