bluecode-2024D-任务处理

245 阅读2分钟

时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 128MB,其他语言 256MB
难度:困难

描述

在某个项目中有多个任务(用 tasks 数组表示)需要您进行处理,其中 tasks[i] = [si, ei],你可以在 si<= day<=ei中的任意一天处理该任务。请返回你可以处理的最大任务数。 

注:一天可以完成一个任务的处理。

输入描述

第一行为任务数量n,1 <= n <= 100000。

后面n行表示各个任务的开始时间和终止时间,用si和ei表示,1 <= si <= ei <= 100000

输出描述

输出为一个整数,表示可以处理的最大任务数。

用例输入 1 **

3
1 1
1 2
1 3

用例输出 1 **

3
// 优先队列
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

int maxTasks(vector<pair<int, int>>& tasks) {
    // 按照开始时间排序
    sort(tasks.begin(), tasks.end());
    
    // 小根堆存储任务的结束时间
    priority_queue<int, vector<int>, greater<int>> pq;
    
    int maxDay = 0;
    // 找到最大的结束时间
    for (auto& task : tasks) {
        maxDay = max(maxDay, task.second);
    }
    
    int taskCount = 0;  // 记录处理的任务数
    int taskIndex = 0;  // 当前处理的任务索引
    
    // 遍历每一天
    for (int day = 1; day <= maxDay; day++) {
        // 将当天可以开始的任务加入小根堆
        while (taskIndex < tasks.size() && tasks[taskIndex].first <= day) {
            pq.push(tasks[taskIndex].second);
            taskIndex++;
        }
        
        // 移除已经过期任务
        while (!pq.empty() && pq.top() < day) {
            pq.pop();
        }
        
        // 如果有任务可以执行,选择截止时间最近的执行
        if (!pq.empty()) {
            pq.pop();
            taskCount++;
        }
    }
    
    return taskCount;
}

int main() {
    int n;
    cin >> n;
    
    vector<pair<int, int>> tasks(n);
    for (int i = 0; i < n; i++) {
        cin >> tasks[i].first >> tasks[i].second;
    }
    
    cout << maxTasks(tasks) << endl;
    
    return 0;
}
// 并查集
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class UnionFind {
private:
    vector<int> parent;
public:
    UnionFind(int size) {
        parent.resize(size + 2); // 1-based to size
        for (int i = 0; i <= size + 1; ++i) {
            parent[i] = i;
        }
    }
    
    int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
    
    void unite(int x) {
        int rootX = find(x);
        int rootY = find(x + 1);
        if (rootX != rootY) {
            parent[rootX] = rootY;
        }
    }
};

int maxTasks(vector<vector<int>>& tasks) {
    sort(tasks.begin(), tasks.end(), [](const vector<int>& a, const vector<int>& b) {
        return a[1] < b[1];
    });
    
    int maxDay = 0;
    for (const auto& task : tasks) {
        if (task[1] > maxDay) {
            maxDay = task[1];
        }
    }
    
    UnionFind uf(maxDay + 1);
    int count = 0;
    
    for (const auto& task : tasks) {
        int s = task[0];
        int e = task[1];
        int day = uf.find(s);
        if (day <= e) {
            count++;
            uf.unite(day);
        }
    }
    
    return count;
}

int main() {
    int n;
    cin >> n;
    vector<vector<int>> tasks(n, vector<int>(2));
    for (int i = 0; i < n; ++i) {
        cin >> tasks[i][0] >> tasks[i][1];
    }
    
    cout << maxTasks(tasks) << endl;
    
    return 0;
}