Work Scheduling G( 洛谷 - P2949 )

Work Scheduling G( 洛谷 - P2949 )

[USACO09OPEN] Work Scheduling G(反悔贪心)

题面翻译

约翰有太多的工作要做。为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间。 他的工作日从 0 0 0 时刻开始,有 1 0 9 10^9 109 个单位时间。在任一时刻,他都可以选择编号 1 1 1 N N N N ( 1 ≤ N ≤ 1 0 5 ) N(1 \leq N \leq 10^5) N(1N105) 项工作中的任意一项工作来完成。 因为他在每个单位时间里只能做一个工作,而每项工作又有一个截止日期,所以他很难有时间完成所有N个工作,虽然还是有可能。 对于第 i i i 个工作,有一个截止时间 D i ( 1 ≤ D i ≤ 1 0 9 ) D_i(1 \leq D_i \leq 10^9) Di(1Di109),如果他可以完成这个工作,那么他可以获利 P i ( 1 ≤ P i ≤ 1 0 9 ) P_i( 1\leq P_i\leq 10^9 ) Pi(1Pi109). 在给定的工作利润和截止时间下,约翰能够获得的利润最大为多少.

题目描述

Farmer John has so very many jobs to do! In order to run the farm efficiently, he must make money on the jobs he does, each one of which takes just one time unit.

His work day starts at time 0 and has 1,000,000,000 time units (!). He currently can choose from any of N (1 <= N <= 100,000) jobs

conveniently numbered 1…N for work to do. It is possible but

extremely unlikely that he has time for all N jobs since he can only work on one job during any time unit and the deadlines tend to fall so that he can not perform all the tasks.

Job i has deadline D_i (1 <= D_i <= 1,000,000,000). If he finishes job i by then, he makes a profit of P_i (1 <= P_i <= 1,000,000,000).

What is the maximum total profit that FJ can earn from a given list of jobs and deadlines? The answer might not fit into a 32-bit integer.

输入格式

* Line 1: A single integer: N

* Lines 2…N+1: Line i+1 contains two space-separated integers: D_i and P_i

输出格式

* Line 1: A single number on a line by itself that is the maximum possible profit FJ can earn.

样例 #1

样例输入 #1
3 
2 10 
1 5 
1 7
样例输出 #1
17

提示

Complete job 3 (1,7) at time 1 and complete job 1 (2,10) at time 2 to maximize the earnings (7 + 10 -> 17).

题目大意:

约翰有很多工作要做,每个工作有一个截止时间和利润。他的工作日从时间 0 开始,且有非常多的时间单位(最多到 (10^9))。每个工作占用一个时间单位。如果约翰能够在截止时间之前完成某项工作,他就能获得该项工作对应的利润。问题要求计算出他能通过合理安排工作的方式,获得的最大利润。

解题思路:

  1. 排序

    • 首先,可以将所有工作按截止时间 (D_i) 升序排序。因为如果工作安排不合理,可能会错过截止时间,排序后方便我们考虑如何在每个时间点选择最优工作。
  2. 使用优先队列

    • 为了使得在有限的时间内获取最大利润,我们可以使用一个优先队列(最小堆)。该堆中存储的是已选择工作的利润。
    • 每次安排一个工作时,如果当前时间点能安排更多的工作,我们就将该工作加入队列。如果队列已满(即已经安排了足够的工作),并且当前工作的利润大于队列中的最小值,则替换队列中的最小值,确保队列内的工作都是利润较高的工作。
  3. 详细步骤

    • 将工作按截止时间排序,遍历每个工作,判断是否可以在截止时间之前完成。
    • 如果能完成该工作并且时间尚余,就将该工作的利润加入堆中。否则,若队列已满且当前工作利润更高,则替换堆中最小的利润。
    • 最后,堆中存储的即为约翰能够完成的所有工作,并且其总利润即为答案。

代码分析:

#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <bitset>
#include <iomanip>
#define endl '\n'
#define int long long
#define Max(a, b) (((a) > (b)) ? (a) : (b))
#define Min(a, b) (((a) < (b)) ? (a) : (b))
#define BoBoowen ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;const int inf = 1e9 + 7;
const int N = 2e5 + 10;
struct Node
{int tim; // 截止时间int mon; // 利润
} node[N];int cmp(struct Node &x, struct Node &y)
{return x.tim < y.tim;  // 按截止时间排序
}void solved()
{int n;cin >> n;for (int i = 0; i < n; ++i){cin >> node[i].tim >> node[i].mon;  // 输入截止时间和利润}sort(node, node + n, cmp);  // 按截止时间升序排序priority_queue<int, vector<int>, greater<int>> pq;  // 最小堆,用于存储当前选择的工作利润for (int i = 0; i < n; ++i){if (node[i].tim > pq.size())  // 如果可以再安排一个工作{pq.push(node[i].mon);  // 将当前工作的利润加入堆中}else  // 如果堆已满,比较当前工作利润是否能替换掉堆中最小的利润{if (node[i].mon > pq.top()){pq.pop();  // 弹出最小的pq.push(node[i].mon);  // 插入当前的工作}}}int ans = 0;while (!pq.empty())  // 最后计算总利润{ans += pq.top();pq.pop();}cout << ans;  // 输出最大利润
}signed main()
{BoBoowen;int T = 1; // 可以扩展到多组测试while (T--){solved();  // 调用解题函数}
}

解题分析:

  1. 排序

    • 首先按截止时间排序,确保我们优先考虑截止时间较早的工作。
  2. 优先队列(最小堆)

    • 优先队列用于存储当前选择的工作。通过最小堆的特性,我们可以在每次选择工作时快速替换掉利润最小的工作,以保证每次都选择最优的工作。
  3. 时间复杂度

    • 排序的时间复杂度为 (O(N \log N))。
    • 使用优先队列的操作(插入和弹出)的时间复杂度为 (O(\log N))。
    • 因此,总的时间复杂度为 (O(N \log N)),适合 (N \leq 10^5) 的规模。

总结:

通过排序和优先队列的组合,能够高效地选择出能够完成的最大利润工作,且时间复杂度适应大规模输入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/7218.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言精粹:深入探索字符串函数

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文&#xff08;1&#xff09;常见字…

微信阅读网站小程序的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

RabbitMQ 死信队列

文章目录 前言1、死信交换机 DLX 与死信队列 DLQ2、死信队列的实现2.1、声明原队列信息2.2、声明死信队列信息2.3、完整示例 3、死信消息流转原理 前言 消息过期以后&#xff0c;如果没有任何配置&#xff0c;是会直接丢弃的。我们可以通过配置让这样的消息变成死信&#xff0…

《边界感知的分而治之方法:基于扩散模型的无监督阴影去除解决方案》学习笔记

paper&#xff1a;Boundary-Aware Divide and Conquer: A Diffusion-Based Solution for Unsupervised Shadow Removal 目录 摘要 1、介绍 2、相关工作 2.1 阴影去除 2.2 去噪扩散概率模型&#xff08;Denoising Diffusion Probabilistic Models, DDPM&#xff09; 3、方…

leetcode28-找出字符串中第一个匹配的下标

leetcode 28 思路 首先循环haystack&#xff0c;然后当当前字符和needle的首字母相同的时候截取出长度等于needle的字符串&#xff0c;进行比较是否相等&#xff0c;如果相等则说明当前index为第一个匹配的下标&#xff0c;如果不相等则说明不正确继续进行遍历&#xff0c;直…

【esp32-uniapp】uniapp小程序篇02——引入组件库

一、引入组件库&#xff08;可自行选择其他组件库&#xff09; 接下来介绍colorUI、uview plus的安装&#xff0c;其他的安装可自行查找教程 1.colorUI weilanwl/coloruicss: 鲜亮的高饱和色彩&#xff0c;专注视觉的小程序组件库 下载之后解压&#xff0c;将\coloruicss-ma…

YOLOv8改进,YOLOv8检测头融合DynamicHead,并添加小目标检测层(四头检测),适合目标检测、分割等,全网独发

摘要 作者提出一种新的检测头,称为“动态头”,旨在将尺度感知、空间感知和任务感知统一在一起。如果我们将骨干网络的输出(即检测头的输入)视为一个三维张量,其维度为级别 空间 通道,这样的统一检测头可以看作是一个注意力学习问题,直观的解决方案是对该张量进行全自…

Vue2官网教程查漏补缺学习笔记 - 3Vue实例4模板语法5计算属性监听器

3 Vue实例 3.1 创建一个 Vue 实例 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的&#xff1a; var vm new Vue({// 选项 })虽然没有完全遵循 MVVM 模型&#xff0c;但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的缩写) 这个变…

【高项】6.3 排列活动顺序 ITTO

输入 项目管理计划组件&#xff1a; ① 进度管理计划&#xff1b;② 范围基准 项目文件&#xff1a; ① 假设日志&#xff1b;② 活动属性&#xff1b;③ 活动清单&#xff1b;④ 里程碑清单 工具与技术 紧前关系绘图法&#xff08;PDM&#xff09; ① 完成到开始&…

将Deepseek接入本地Vscode

第一步&#xff1a;获取Deepseek APIKEY 1.1 登录Deepseek官网 https://www.deepseek.com/ 1.2 选择API开放平台 1.3 注册账号并登录 1.4 登录成功后的就界面 1.5 点击左侧菜单栏“API keys”&#xff0c;并创建API key 名称自定义输入 生成API key 复制保存&#xff0c;丢失…

docker使用笔记

文章目录 1.Docker 与容器2.核心概念与安装配置2.1 核心概念2.2 docker 安装ubuntu使用官方的脚本自动安装准备条件准备安装安装Docker安装Docker 命令补全工具允许非Root用户执行docker 命令最后一步 更新.bashrc文件 [修改docker 默认的存储路径](https://www.cnblogs.com/du…

vim如何设置制表符表示的空格数量

:set tabstop4 设置制表符表示的空格数量 制表符就是tab键&#xff0c;一般默认是四个空格的数量 示例&#xff1a; &#xff08;vim如何使设置制表符表示的空格数量永久生效&#xff1a;vim如何使相关设置永久生效-CSDN博客&#xff09;

PPT添加与管理批注的操作指南

​​​ 批注是PPT中一个非常实用的功能&#xff0c;它不仅能帮助我们在演讲和设计过程中记录想法&#xff0c;还能与他人协作时提供有价值的反馈。无论是团队讨论、审稿&#xff0c;还是个人思考&#xff0c;批注的运用都能让我们的PPT更加完善和高效。我会详细介绍如何在PPT中…

CASAIM与友达光电达成深度合作,CASAIM IS自动化蓝光测量技术为创新显示技术发展注入新的活力

近期&#xff0c;CASAIM与友达光电股份有限公司在液晶显示面板智能自动三维检测技术上达成深度合作&#xff0c;联合打造CASAIM IS全自动化智能检测系统,助力光电产品显示面板制造全自动化3d测量&#xff0c;实现高精度、高效率测量和检测&#xff0c;进一步提升产品质量和生产…

【已解决】OSS配置问题

OSS SDK快速入门_对象存储(OSS)-阿里云帮助中心 阿里官方的SDK使用方法还得配置环境变量access Key、access Secret &#xff0c;我没有配置&#xff0c;仅把access Key和access Secret写到了yml文件读取&#xff0c;结果上传图片时还是出现下面的问题。 [ ERROR ] [ com.s…

STM32 硬件I2C读写

单片机学习&#xff01; 目录 前言 一、步骤 二、配置I2C外设 2.1 开启I2C外设和GPIO口时钟 2.2 GPIO口初始化为复用开漏模式 2.3 结构体配置I2C 2.4 使能I2C 2.5 配置I2C外设总代码 三、指定地址写时序 3.1 生产起始条件S 3.2 监测EV5事件 3.3 发送从机地址 3.4 …

C语言程序设计十大排序—冒泡排序

文章目录 1.概念✅2.冒泡排序&#x1f388;3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅ 1.概念✅ 排序是数据处理的基本操作之一&#xff0c;每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法&#xff0c;排序后的数据更易于处理和查找。在计算机发展…

Python网络自动化运维---用户交互模块

文章目录 目录 文章目录 前言 实验环境准备 一.input函数 代码分段解析 二.getpass模块 前言 在前面的SSH模块章节中&#xff0c;我们都是将提供SSH服务的设备的账户/密码直接写入到python代码中&#xff0c;这样很容易导致账户/密码泄露&#xff0c;而使用Python中的用户交…

【后端开发】字节跳动青训营之性能分析工具pprof

性能分析工具pprof 一、测试程序介绍二、pprof工具安装与使用2.1 pprof工具安装2.2 pprof工具使用 资料链接&#xff1a; 项目代码链接实验指南pprof使用指南 一、测试程序介绍 package mainimport ("log""net/http"_ "net/http/pprof" // 自…

【Ubuntu】安装SSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端&#xff1a; sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端&#xff1a; sudo systemctl start ssh贰、配置SSH&#xff08;可跳过&#xff09; 配置文件 …