工作安排

工作安排#

题目地址: 2022/3/13

题目描述#

约翰有太多的工作要做。

为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间。

他的工作日从 0 时刻开始,有 109 个单位时间。

在任一时刻,他都可以选择编号 1NN 项工作中的任意一项工作来完成。

每项工作又有一个截止日期,对于第 i 个工作,有一个截止时间 Di,如果他可以完成这个工作,那么他可以获利 Pi

在给定的工作利润和截止时间下,约翰能够获得的利润最大为多少。

数据范围: 1N105,0Di,Pi109

思路#

注意到每个工作的工作时间都是 1,因此对于某个时间,我们选最大的获利一定是最优的,那么我们考虑把所有的工作按照价值排序,从大到小枚举每一个工作,尽量选最靠近 Pi 的时间,这样才可以使其他的工作有更有可能被做。
因此我们可以用 并查集 快速的找到在 Pi 之间最近的没有被用过的时间。

CODE
#include <unordered_map>
#include <stdio.h>
#include <algorithm>

struct node {
	int ddl, w;
	bool operator < (const node &T) const {
		return w > T.w;
	}
}a[100010];

std::unordered_map<int, int> f; //由于值域太大,我们用 unordered_map 当做离散化后的并查集

int find(int x) {
	if(!f.count(x)) f[x] = x;
	if(f[x] != x) f[x] = find(f[x]);
	return f[x];
}

int main() {
	int n; scanf("%d", &n);
	for(int i = 1; i <= n; i ++ ) {
		scanf("%d%d", &a[i].ddl, &a[i].w);
	}
	std::sort(a + 1, a + 1 + n);
	long long ans = 0;
	for(int i = 1; i <= n; i ++ ) {
		int k = find(a[i].ddl);
		if(k <= 0) continue;
		ans += a[i].w;
		f[k] = k - 1;
	}
	printf("%lld\n", ans);
	return 0;
}

posted @   ccz9729  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩