E卷-可以处理的最大任务数-(200分)

E卷-刷题笔记合集🔗

可以处理的最大任务数

问题描述

LYA 是一家公司的项目经理,她需要安排公司的多个项目任务。每个任务都有一个开始时间和结束时间。LYA 希望在给定的时间范围内安排尽可能多的任务。

具体来说,给定一个任务列表 ,其中 表示第 个任务的开始时间为 ,结束时间为 。LYA 可以在 的任意一天处理该任务。请帮助 LYA 找出她可以处理的最大任务数。

输入格式

第一行包含一个正整数 ,表示任务的数量。

接下来 行,每行包含两个正整数 ,表示第 个任务的开始时间和结束时间。

输出格式

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

样例输入1

3
1 1
1 2
1 3

样例输出1

3

样例输入2

5
1 2
2 3
3 4
1 3
2 4

样例输出2

4

样例解释

样例 解释说明
样例1 LYA 可以在第 1 天处理所有三个任务。
样例2 LYA 可以在第 1 天处理任务 [1,2],第 2 天处理任务 [2,3],第 3 天处理任务 [3,4],第 4 天处理任务 [2,4],共计 4 个任务。

数据范围

题解

这道题目可以使用贪心算法结合优先队列(最小堆)来解决。解题思路如下:

  1. 首先,将所有任务按照开始时间进行分组。这样可以快速找到每一天开始的任务。

  2. 遍历时间轴(从第 1 天到第 100000 天),对于每一天:

    • 移除优先队列中已经结束的任务。
    • 将当天开始的所有任务的结束时间加入优先队列。
    • 如果优先队列不为空,说明有可以执行的任务,选择一个任务执行(优先队列自动选择结束时间最早的任务)。
  3. 统计执行的任务总数,即为最大可执行任务数。

参考代码

  • Python
import heapq

def solve(tasks):
    max_tasks = 0  # 记录最大任务数
    pq = []  # 使用优先队列(最小堆)作为待处理队列

    # 遍历时间轴(假设最大时间为 100000)
    for day in range(100005):
        # 移除已经结束的任务
        while pq and pq[0] < day:
            heapq.heappop(pq)

        # 将当前时刻开始的任务加入队列
        if day in tasks:
            for end_day in tasks[day]:
                heapq.heappush(pq, end_day)

        # 如果队列不为空,处理一个任务(结束时间最早的任务)
        if pq:
            max_tasks += 1
            heapq.heappop(pq)

    return max_tasks

# 读取输入
n = int(input())  # 输入任务数量
tasks = {}  # 存储任务的开始和结束时间

# 读取每个任务的开始和结束时间
for _ in range(n):
    start, end = map(int, input().split())
    if start in tasks:
        tasks[start].append(end)
    else:
        tasks[start] = [end]

# 输出结果
print(solve(tasks))
  • C
#include <stdio.h>
#include <stdlib.h>

#define MAX_DAY 100005
#define MAX_TASKS 100000

// 最小堆结构
typedef struct {
    int* heap;
    int size;
} MinHeap;

// 初始化最小堆
void initMinHeap(MinHeap* h, int capacity) {
    h->heap = (int*)malloc(sizeof(int) * capacity);
    h->size = 0;
}

// 向上调整堆
void heapifyUp(MinHeap* h, int i) {
    int temp = h->heap[i];
    while (i > 0 && temp < h->heap[(i - 1) / 2]) {
        h->heap[i] = h->heap[(i - 1) / 2];
        i = (i - 1) / 2;
    }
    h->heap[i] = temp;
}

// 向下调整堆
void heapifyDown(MinHeap* h, int i) {
    int temp = h->heap[i];
    int child;
    while (2 * i + 1 < h->size) {
        child = 2 * i + 1;
        if (child + 1 < h->size && h->heap[child + 1] < h->heap[child]) {
            child++;
        }
        if (temp <= h->heap[child]) break;
        h->heap[i] = h->heap[child];
        i = child;
    }
    h->heap[i] = temp;
}

// 插入元素到堆
void push(MinHeap* h, int val) {
    h->heap[h->size] = val;
    heapifyUp(h, h->size);
    h->size++;
}

// 弹出堆顶元素
int pop(MinHeap* h) {
    int top = h->heap[0];
    h->heap[0] = h->heap[--h->size];
    heapifyDown(h, 0);
    return top;
}

int solve(int tasks[][2], int n) {
    MinHeap pq;
    initMinHeap(&pq, MAX_TASKS);
    int max_tasks = 0;
    int task_index = 0;

    for (int day = 1; day <= MAX_DAY; day++) {
        // 移除已经结束的任务
        while (pq.size > 0 && pq.heap[0] < day) {
            pop(&pq);
        }

        // 将当前时刻开始的任务加入队列
        while (task_index < n && tasks[task_index][0] == day) {
            push(&pq, tasks[task_index][1]);
            task_index++;
        }

        // 如果队列不为空,处理一个任务
        if (pq.size > 0) {
            max_tasks++;
            pop(&pq);
        }
    }

    free(pq.heap);
    return max_tasks;
}

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

HaxyBT:那我提前下班总可以了吧
点赞 评论 收藏
分享
评论
2
2
分享

创作者周榜

更多
牛客网
牛客企业服务