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 ...
随机推荐
- 在windows下安装配置Ulipad
在windows下安装配置Ulipad 今天推荐一款轻便的文本编辑器Ulipad,用来写一些小的Python脚本非常方便. Ulipad下载地址: https://github.com/limodou ...
- mvc5 Html.EditorFor html属性有了新变化,和以前的不同了
@Html.EditorFor(model => model.MaxNumber, new { htmlAttributes = new { @min = "1" } })
- css3实践之图片轮播(Transform,Transition和Animation)
楼主喜欢追求视觉上的享受,虽常以牺牲性能无法兼容为代价却也乐此不疲.本文就通过一个个的demo演示来简单了解下css3下的Transform,Transition和Animation. 本文需要实现效 ...
- SQL 批量修改表结构
项目中发现一批语言表的某个字段设的值太小了需要增大,因为涉及到很多张表,所以采用游标一张张的处理. 代码很简单 ) ) DECLARE LangTable CURSOR FOR SELECT name ...
- 分享:关于之前锤子手机刷MIUI之后,现在有事跌宕起伏的刷回了Smartisan OS!
序言: 距离上次把锤子手机刷成MIUI之后已经一个半月了,我是一个刷机党,一个半月足够让我适应一个系统,了解一个系统.刷机有风险,不过我愿意冒这个风险,因为兴趣,没别的.刷机之后,肯定是有问题的,没 ...
- Castle 多继承选择
Castle 多继承选择 很多时候,我们定义了一个接口,但是这个接口会有多种不同的,这时IOC构造函数注入的时候,就需要自动选择对应的实现. public interface ITestService ...
- C# 序列化与反序列化
我们先说说什么是序列化.所谓的序列化就是把要保存的内容以特定的格式存入某种介质中.比如我们要保存一些数据在下次程序启动的时候再读入.我们一般就是把这个数据写在一个本地的文本中.然后程序启动的时候去读入 ...
- ASP.NET MVC 数据库依赖缓存的实现
当数据库中的信息发生变化的时候,应用程序能够获取变化的通知是缓存依赖得以实现的基础.应用程序可以通过轮询获取数据变化的信息,使用轮询的话也不可能重新查一次后再和以前的数据做比较,如果这样的话如果我一个 ...
- C++成员变量的初始化顺序问题
问题来源: 由于面试题中,考官出了一道简单的程序输出结果值的题:如下, class A { private: int n1; int n2; public: A():n2(0),n1(n2+2){} ...
- php 解析json
今天做项目的时候需要用到json数组,解析时遇到了个小小的麻烦,特此将解决办法记下: json数据如下: { "code":200, "message":&qu ...