有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室?
分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不冲突的活动,安排一个教室之后,剩余的活动再分配一个教室,继续贪心选择……
反例: A:[1,2) B:[1,4) C:[5,6) D:[3,7)
已经按结束时间排好顺序,我们会选择
教室1: A C
教室2: B
教室3: D
需要3个教室。
但是如果换一种安排方法,我们可以安排AD在一个教室,而BC在另外一个教室,两个教室就够了。
如果只需要教室的个数,我们可以把所有开始时间和结束时间排序,遇到开始时间就把厚度加1,遇到结束时间就把厚度减1,显然最初始和最后结束时的厚度是0,在一系列厚度变化的过程中,峰值(最大值)就是最多同时进行的活动数,也是我们至少需要的教室数。
PS:其实要区别开始时间与结束时间,用一个辅助数组做为每一个时间的标志(判断是开始时间还是结束时间)。还有就是为处理A,B两个数组中的标志,不能让A中任何一个到n之后去退出循环了,取A,B中标志i,j的较小值。(感觉自己语言都混乱了…..)
c++:
#include<stdio.h>
#include<algorithm>
#include<iostream>
long int b[10100];
long int a[10010];
long int c[20100];
int d[20100];
using namespace std;
int main()
{
int n;
cin>>n;
int i;
for (int i = 0; i < n;i++ )
{
cin>>a[i];
cin>>b[i];
}
int j=0;
long int ok=0,k=0,z;
long int t;
z=min(j,i);
sort(a,a+n);
sort(b,b+n);
for(i=0,j=0;z<n;){
if(b[i]>a[j]&&j!=n){c[k]=a[j];
d[k++]=1;
j++;
}
if(a[j]>=b[i]&&i!=n){c[k]=b[i];
d[k++]=0;
i++;
}
if(i==n){c[k]=b[j];
d[k++]=0;
j++;
}
if(j==n){c[k]=a[i];
d[k++]=0;
i++;
}
z=min(i,j);
}
for (int i = 0; i < 2*n; ++i)
{
if(d[i]){ok++;
}
else{ok--;
}
if(ok>t){t=ok;
}
}
printf("%d\n",t );
return 0;
}