奶牛Bessie工作调度:如何最大化完成工作数量?
这个问题是一个经典的任务调度问题,目标是选择尽可能多的工作,使得每个工作都能在截止时间前开始并完成。 我们可以将工作按照截止时间 \( s_i \) 排序,然后使用一个优先队列(大根堆)来维护已选择的工作的耗时。 算法思路: 1. 将所有工作按 \( s_i \) 从小到大排序。 2. 遍历每个工作: - 将当前工作加入已选集合(将 \( t_i \) 加入优先队列,并累加总耗时 `sum_t`)。 - 如果 `sum_t > s_i`,说明当前已选工作无法全部在截止时间前完成,则移除耗时最长的工作(优先队列中最大的 \( t \)),并更新 `sum_t`。 3. 最终优先队列的大小就是能完成的最大工作数。 时间复杂度: 排序 \( O(N \log N) \),每个工作最多一次入堆和出堆,也是 \( O(N \log N) \),总复杂度 \( O(N \log N) \),可以处理 \( N \leq 2\times 10^5 \) 的数据。 C++ 实现: ```cpp #include <iostream> #include <vector> #include <algorithm> #include <queue> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; while (T--) { int N; cin >> N; vector<pair<long long, long long>> jobs(N); for (int i = 0; i < N; i++) { cin >> jobs[i].first >> jobs[i].second; } // 按 s_i 排序 sort(jobs.begin(), jobs.end()); priority_queue<long long> pq; // 大根堆,存放已选工作的耗时 long long sum_t = 0; for (auto& job : jobs) { long long s = job.first, t = job.second; pq.push(t); sum_t += t; if (sum_t > s) { // 移除耗时最长的工作 sum_t -= pq.top(); pq.pop(); } } cout << pq.size() << "\n"; } return 0; } ``` ######[AI问答 | 494点数解答 | 2026-01-18 12:55:29]
- 易语言读取文本文件并显示到超级列表框:代码示例与注意要点(DeepSeek | 571点数解答 | 2025-08-23 20:54:40)224
- 易语言:读取并显示特定文本到超级列表框,还能增加新数据的方法与要点(DeepSeek | 1317点数解答 | 2025-08-23 20:58:40)230
- 奶牛Bessie工作调度:如何最大化完成工作数量?(DeepSeek | 494点数解答 | 2026-01-18 12:55:29)33
- 奶牛Bessie的工作调度:基于截止时间的贪心反悔算法实现(阿里通义 | 3592点数解答 | 2026-03-05 12:23:20)16
- 小核桃破密码遇进度条:补全代码实现百分比加载及完成提示 (字节豆包 | 326点数解答 | 2025-12-13 20:06:10)48
- 小核桃补全代码:实现进度条加载信息输出(字节豆包 | 53点数解答 | 2026-01-10 19:26:25)40
- 小核桃解门密遇进度条,代码补全助其加载完成!(字节豆包 | 90点数解答 | 2026-01-10 19:26:42)35
- 小核桃破解密码遇进度条!C++代码补全助其完成加载(百度文心 | 231点数解答 | 2026-01-10 19:57:04)41
- mallshop商城网站:数据库设计与强大业务功能全揭秘(GPT | 257点数解答 | 2024-12-09 14:08:15)275
- C++ 代码揭秘:小核桃大门密码进度条代码解析(字节豆包 | 320点数解答 | 2025-11-28 19:40:52)71
- C++ 代码:助小核桃根据输入整数输出进度及完成提示(字节豆包 | 338点数解答 | 2025-11-28 19:42:04)53
- 小核桃破密码遇进度条:补全代码实现进度输出逻辑(字节豆包 | 106点数解答 | 2025-12-27 20:58:56)44