Hong Kong Regional Online Preliminary 2016 C. Classrooms
Classrooms
The new semester is about to begin, and finding classrooms for orientation activities is always a headache.
There are $k$ classrooms on campus and $n$ proposed activities that need to be assigned a venue. Every proposed activity has specfic starting time $s_i$ and ending time $f_i$. Any such an activity should take place at one of the classrooms. Any of the $k$ classrooms is big enough to hold any of the proposed activities, and each classroom can hold at most one activity at any time. No two proposed activities can take place at the same classroom at the same time. Even if two proposed activities overlap momentarily (the ending time of one activity equals the starting time another activity), they cannot be assigned to the same classroom.
There are so many proposed activities that there may not be enough classrooms to hold all the activities. It is desirable to have as many activities as possible. At most how many proposed activities can be assigned to the classrooms?
Input
The first line contains two positive integers $n$ and $k$ ($k \le n \le 200000$), representing the number of proposed activities and number of classrooms, respectively.
The following $n$ lines each contains two positive integers: the $i$-th line among these $n$ lines contains $s_i$ and $f_i$ ($1 \le s_i \le f_i \le 10^9$), indicating the starting time and ending time of proposed activity $i$.
Output
Output an integer indicating the maximum number proposed activities that can be scheduled.
Sample Input 1
4 2
1 4
2 9
4 7
5 8
Sample Output 1
3
Solution
从前在《挑战程序设计竞赛》看到过一个结论:
在$n$个区间$[l_1, r_1],\cdots, [l_n, r_n]$中选择最多的两两不相交的区间, 可按如下贪心策略:
每次都选当前可选的区间中结束时间最早的那个区间.
其实这是个求DAG上最长链的问题.
上述情形恰好是本题的一个特例 ($k=1$), 所以我第一个想法是:
将所有区间按右端点从大到小排序.
按此顺序将区间放到一个链表 (std::list) 里, 每次按上述贪心策略, 选择一个最长链, 并将这些区间从链表中删除.
可惜这做法是错的, 而且复杂度是$O(n^2)$.
然后就不知道怎么做了. 我做题有个不好的习惯: 每次WA后, 不会去动手出几组数据check以下, 验证自己想法的正确性.
其实对于我的做法反例很容易举出来:
后来在某博客上看到了正确的做法:
基本的想法也是对一个贪心策略的模拟:
仍然先将区间按右端点从小到大排序, 从左到右遍历这些区间, 同时用 std::multiset<int> 维护每个房间内当前正在进行那个活动的结束时间 (亦即区间右端点). 对于当前考虑的区间 $[l_i, r_i]$, 在multiset中查询小于 (早于) $l_i$的最大的某个右端点, $r^$. 若$r^$存在就将其更新为$r_i$, 否则若multiset的size()$<k$就将$r_i$插入multiset.
Implementation
考虑到std::multiset<>只支持lower_bound()和upper_bound, 为了方便上述查询, 将区间右端点的相反数 (负值) 插入multiset中.
#include <bits/stdc++.h>
using namespace std;
const int N{1<<18};
struct X{
int s, t;
void read(){
scanf("%d%d", &s, &t);
}
bool operator<(const X &rhs)const{
return t<rhs.t;
}
void out(){
cout<<s<<' '<<t<<endl;
}
}a[N];
multiset<int> mst;
int main(){
int n, k;
cin>>n>>k;
for(int i=0; i<n; i++)
a[i].read();
sort(a, a+n);
int res=0;
for(int i=0; i<n; i++){
// a[i].out();
auto it=mst.upper_bound(-a[i].s);
if(it==mst.end()){
if(mst.size()<k){
// puts("ADD1");
res++;
mst.insert(-a[i].t);
}
}
else{
res++;
// puts("ADD2");
mst.erase(it);
mst.insert(-a[i].t);
}
}
cout<<res<<endl;
return 0;
}
当然, 取相反数也可以实现上述查询, 这时这要查询low_bound(r[i])的前趋.
#include <bits/stdc++.h>
using namespace std;
const int N{1<<18};
struct X{
int s, t;
void read(){
scanf("%d%d", &s, &t);
}
bool operator<(const X &rhs)const{
return t<rhs.t;
}
void out(){
cout<<s<<' '<<t<<endl;
}
}a[N];
multiset<int> mst;
int main(){
int n, k;
cin>>n>>k;
for(int i=0; i<n; i++)
a[i].read();
sort(a, a+n);
int res=0;
for(int i=0; i<n; i++){
// a[i].out();
auto it=mst.lower_bound(a[i].s);
if(it==mst.begin()){
if(mst.size()<k){
// puts("ADD1");
res++;
mst.insert(a[i].t);
}
}
else{
res++;
--it;
// puts("ADD2");
mst.erase(it);
mst.insert(a[i].t);
}
}
cout<<res<<endl;
return 0;
}
总结
这个贪心策略的正确性还是比较容易证明的.
首先将区间按活动的结束时间从早到晚排序, 按这样的顺序出个安排活动能够保证当对于任意两个相互冲突的两个活动, 我们优先选择结束时间较早的活动, 这显然比选结束时间晚的要更优.
Hong Kong Regional Online Preliminary 2016 C. Classrooms的更多相关文章
- Asia Hong Kong Regional Contest 2016
A. Colourful Graph 可以在$2n$步之内实现交换任意两个点的颜色,然后就可以构造出方案. #include <bits/stdc++.h> using namespace ...
- 2019-2020 ICPC Asia Hong Kong Regional Contest
题解: https://files.cnblogs.com/files/clrs97/19HKEditorial-V1.zip Code:(Part) A. Axis of Symmetry #inc ...
- Asia Hong Kong Regional Contest 2019
A. Axis of Symmetry B. Binary Tree n 的奇偶性决定胜负. C. Constructing Ranches 路径上点权之和大于,极大值两倍,这是路径上点能拼出多边形的 ...
- 2019-2020 ICPC Asia Hong Kong Regional Contest J. Junior Mathematician 题解(数位dp)
题目链接 题目大意 要你在[l,r]中找到有多少个数满足\(x\equiv f(x)(mod\; m)\) \(f(x)=\sum_{i=1}^{k-1} \sum_{j=i+1}^{k}d(x,i) ...
- 每日英语:Google Scraps Plan to Build Hong Kong Data Center
Internet giant Google Inc. has scrapped a plan to build its own data center in Hong Kong and will in ...
- 每日英语:Hong Kong Lifestyle Strains City's Resources
Hong Kong's rapacious consumption and waste production is straining its natural resources and could ...
- Neon Lights in Hong Kong【香港霓虹灯】
Neon Lights in Hong Kong Neon is to Hong Kong as red phone booths are to London and fog is to San Fr ...
- URAL 1969. Hong Kong Tram
有一个trick就是没想到,枚举第二段时间后,要检测该火车能否继续跑一圈来判断,不能先检测前半圈能不能跑加进去后在检测后半段: // **** 部分不能放在那个位置: 最近代码导致的错误总是找不出,贴 ...
- 2016-2017 ACM-ICPC East Central North America Regional Contest (ECNA 2016) F 区间dp
Problem F Removal GameBobby Roberts is totally bored in his algorithms class, so he’s developed a li ...
随机推荐
- 与Python Falling In Love_Python跨台阶(面向对象)
第二课会介绍Python中的一些变量的使用.列表.元组.字典等一些详细内容...篇幅会比较多...因此在整理中... 先跳过第二课...直接来第三课..Python中面向对象的学习以及与mysql数据 ...
- OS存储器管理(一)
存储器的层次: 分为寄存器.主存(内存)和 辅存(外存)三个层次. 主存:高速缓冲存储器.主存储器.磁盘缓冲存储器, 主存又称为可执行存储器: 辅存:固定磁盘存储器.可移动的外部存储器: 其可长期保存 ...
- [BZOJ3696][FJSC2014]化合物(异或规则下的母函数)
题目:http://hzwer.com/3708.html 分析: 类似树分治思想,设f[x][i]表示以x为根的子树的所有点中,与x的距离为i的点有多少个,这个可以预处理出来 然后我们考虑每颗子树对 ...
- Android开发之Menu和actionBar
一.通过Menu目录下创建一个布局文件: 先看代码meu/main.xml: <?xml version="1.0" encoding="utf-8"?& ...
- js浏览器窗口
一.clientwidth和clientheight 注:返回了元素大小,但没有单位,默认单位是 px,如果你强行设置了单位,比如 100em之类,它还是会返回 px的大小. (CSS获取的话,是照着 ...
- oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务。
来源于:http://www.cnblogs.com/wangfg/p/5110831.html 一.查询系统中的job,可以查询视图 --相关视图 select * from dba_jobs; s ...
- iOS开发小技巧--TableView中headerView的循环利用,以及自定义的headerView
一.首先要搞清楚,tableView中有两种headerView,一个是tableHeaderView,另一个是headerView.前者就一个;后者根据session决定个数 headerView的 ...
- 同 一个页面,不同请求路径,如何根据实际场景写JS
场景:使用同一个“添加群成员”的页面来操作 建群页面:建群成功后,返回查看群成员页面.在建群过程中直接添加群成员并返回一个群名称的参数. 添加群成员页面:在巳有群内添加群成员,添加成功后,返回查看群成 ...
- git之旅【第二篇】
1,git的安装 最早Git是在Linux上开发的,很长一段时间内,Git也只能在Linux和Unix系统上跑.不过,慢慢地有人把它移植到了Windows上.现在,Git可以在Linux.Unix.M ...
- 关于API认证的问题
问题:如何保证api安全?-->做api的认证 如下图 整个过程大概就是这样. 好像没什么可以讲的....