题目描述
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的 贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个 顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小 会场数。)
##输入描述
第一行有 1 个正整数k,表示有 k个待安排的活动。 接下来的 k行中,每行有 2个正整数,分别表示 k个待安排的活动开始时间和结束时间。时间 以 0 点开始的分钟计。
输出描述
输出最少会场数。
整体思路
首先注意和下面一种情况区分开:
一个会场,怎样安排最多活动数
这个问题关注的是活动数量,因此可以通过利用会场选活动的方式,每次选择结束时间最早的活动加入会场。
而我们的问题是
一定数量的活动,怎样可以安排入最少的会场
因此可以采用通过活动选会场的方式,对每一个活动进行判断,若当前活动开始时间与已有会场里的活动冲突,就开辟新会场;反之就安排入已有会场。
这里通过一个反例证明为什么第一个问题的解法在第二个问题处不适用:
如果使用第一种解法,我们至少需要3个会场;而使用第二种解法,只需要2个会场。这是因为,第一种解法下,已被安排的会场可能会存在本可以安排其他活动的空闲时间段;而第二种方式时间则是紧密排列的,不会出现该种情况。
完整代码
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; struct node { int begin; int end; int ok=0; } act[maxn]; bool cmp(node a,node b) { return a.begin<b.begin; } int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) { cin>>act[i].begin>>act[i].end; } sort(act,act+n,cmp); int ans=0; for(int i=0;i<n;i++) { if(act[i].ok==0) { ans++; act[i].ok==1; int end=act[i].end; for(int j=i+1;j<n;j++) { if((act[j].begin>=end)&&(act[j].ok==0)) { end=act[j].end; act[j].ok=1; } } } } printf("%d",ans); return 0; }