12.任务安排

目录

题目

Description

Input

Output

思路(排序+贪心算法)

注意事项

1.只关注结束时间即可

2.关于本题sort函数的用法

C++代码

时间复杂度

空间复杂度


题目

Description

小张经常为了事情太多安排不开而苦恼。现在他手头有

n

项任务,每项任务都有一个开始时间

s_i

和结束时间

e_i

。要想完成一个任务必须从开始时间做到结束时间,并且同一时间小张只能进行一项任务。
小张想知道他最多可以完成几项任务。

Input

第一行一个整数

n(1 \leq n \leq 300000 )

,表示小张手头任务的个数。

接下来

n

行,每行两个整数

s_i,e_i(1 \leq s_i < e_i \leq 10^9 )

,表示任务的开始时间和结束时间。

Output

一行一个整数,表示小张最多可以完成几项任务。


思路(排序+贪心算法)

贪心算法是一种在每一步选择中都采取当前最优解的策略,以希望最终能够达到全局最优解的方法。对于这道题,贪心算法的思路如下:

1. 首先,我们将任务按照结束时间进行排序,这样可以确保我们在选择任务时,选择的是结束时间最早的任务。

2. 初始化一个变量`maxTasks`为1,表示小张最多可以完成的任务数量。

3. 从第一个任务开始,依次判断每个任务的开始时间是否在前一个任务的结束时间之后。如果是,则说明这个任务可以执行,将`maxTasks`加1,并更新结束时间为当前任务的结束时间。

4. 继续判断下一个任务,重复步骤3,直到遍历完所有任务。

5. 最后,输出`maxTasks`即为小张最多可以完成的任务数量。

贪心算法的关键在于每一步的选择,我们选择结束时间最早的任务,这样可以腾出更多的时间去执行其他任务,从而最大化完成任务的数量。


注意事项


1.只关注结束时间即可

在这道题中,我们只关心完成任务的数量,而不需要考虑具体选择哪些任务。因此,如果存在多个任务的开始时间相同,我们可以任意选择其中一个任务进行执行,不会影响最终的结果。

假设有两个任务A和B,它们的开始时间相同。如果我们选择执行任务A,那么任务B就无法执行;反之,如果我们选择执行任务B,那么任务A就无法执行。无论我们选择执行哪个任务,最终完成的任务数量都是一样的。

因此,在这道题中,我们只需要按照结束时间进行排序,而不需要考虑开始时间相同的情况。

2.关于本题sort函数的用法

sort()函数是C++标准库中的一个算法函数,用于对容器中的元素进行排序。它的使用方法如下:

#include 

// 比较函数,用于指定排序的规则bool compare(const Type& a, const Type& b) {
    // 返回true表示a排在b的前面,返回false表示a排在b的后面}

// 使用sort函数对容器进行排序sort(container.begin(), container.end(), compare);

其中,container是一个容器,可以是数组、向量、链表等。begin()和end()是容器的迭代器,用于指定排序的范围。compare是一个自定义的比较函数,用于指定排序的规则。

比较函数compare需要满足以下条件:
- 如果a应该排在b的前面,返回true;
- 如果a应该排在b的后面,返回false。

sort()函数会根据比较函数的返回值,对容器中的元素进行排序。默认情况下,sort()函数会按照升序进行排序。

在本题中,我们使用sort()函数对任务按照结束时间进行排序,以便后续的贪心算法能够选择结束时间最早的任务。

C++代码

#include 
#include 
#include 
using namespace std;
//自定义的比较函数
bool compare(const vector& a, const vector& b) {
		return a[1] < b[1];//结束时间早则排在前面
}
int main() {
	int n;
	cin >> n;
	vector> arr(n, vector(2));
	
	for (long long i = 0; i < n; i++) {
		cin >> arr[i][0] >> arr[i][1];
	}
	sort(arr.begin(), arr.end(), compare);//使用sort函数进行排序

	int maxTasks = 1;//第一个任务一定可以完成
	long long endTime = arr[0][1];
	for (long long i = 1; i < n; i++) {
		if (arr[i][0] >= endTime) {
			endTime = arr[i][1];
			maxTasks++;
		}
	}
	cout << maxTasks << endl;
	return 0;
}

时间复杂度

1. 对任务进行排序的时间复杂度为O(nlogn),其中n为任务的个数。
2. 遍历任务的时间复杂度为O(n)。
所以总的时间复杂度为O(nlogn)。

空间复杂度

1. 使用了一个二维数组`tasks`来存储任务的开始时间和结束时间,所以空间复杂度为O(n)。
2. 使用了几个整型变量来存储中间结果,所以空间复杂度为O(1)。
所以总的空间复杂度为O(n)。

你可能感兴趣的:(程序设计方法与实践,算法,c++,数据结构)