usingnamespacestd; structpoint{ int start; int end; }; point a[10000 + 10]; boolcmp(const point a,const point b){ return a.end <= b.end; } intmain(){ //freopen("input.txt", "r", stdin); int m,n; cin >> m; while(m--){ cin >> n; for (int i = 0; i < n;i++){ cin >> a[i].start >> a[i].end; } sort(a, a + n, cmp); int count = 1; int end=a[0].end; for(int i=1;i<n;i++) if(a[i].start>end){ end=a[i].end; count++; } cout << count<<endl; } }
分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不冲突的活动,安排一个教室之后,剩余的活动再分配一个教室,继续贪心选择…… 反例: A:[1,2) B:[1,4) C:[5,6) D:[3,7) 已经按结束时间排好顺序,我们会选择 教室1: A C 教室2: B 教室3: D 需要3个教室。 但是如果换一种安排方法,我们可以安排AD在一个教室,而BC在另外一个教室,两个教室就够了。 所以之前的贪心策略解决不了这个问题。 所以要换种思路,我们可以按开始时间排序,每出现一个活动,若不能添加到当前教室,则增加一个教室。 如何证明此思路的正确性呢?假设当前有K个教室,对新出现的活动进行添加一个教室,说明此时k个活动都在进行,加上新出现的活动,刚好K+1个活动,已达到最优。 以下为具体实现,其中用到了优先级队列,优先级队列是以二叉堆为基础的数据结构。