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 ...
随机推荐
- Ace - Responsive Admin Template
Ace简介: Ace 是一个轻量.功能丰富.HTML5.响应式.支持手机及平板电脑上浏览的管理后台模板,基于CSS框架Bootstrap制作,Bootstrap版本更新至 3.0,Ace – Resp ...
- 与Python Falling In Love_Python跨台阶(面向对象)
第二课会介绍Python中的一些变量的使用.列表.元组.字典等一些详细内容...篇幅会比较多...因此在整理中... 先跳过第二课...直接来第三课..Python中面向对象的学习以及与mysql数据 ...
- 【MVVMLight小记】二.开发一个简单图表生成程序附源码
上一篇文章介绍了怎样快速搭建一个基于MVVMLight的程序http://www.cnblogs.com/whosedream/p/mvvmlight1.html算是简单入门了下,今天我们来做一个稍许 ...
- Linux权限
在Linux中要修改一个文件夹或文件的权限我们需要用到linux chmod命令来做,下面我写了几个简单的实例大家可参考一下. 语法如下: chmod [who] [+ | - | =] [mode] ...
- Web端PHP代码函数覆盖率测试解决方案
1. 关于代码覆盖率 衡量代码覆盖率有很多种层次,比如行覆盖率,函数/方法覆盖率,类覆盖率,分支覆盖率等等.代码覆盖率也是衡量测试质量的一个重要标准,对于黑盒测试来说,如果你不确定自己的测试用例是否真 ...
- [转]acm忠告
多做难题 如果你去问那些牛人“这道题你是怎么想到要用XXX方法的”,我估计大部分人都说不出个所以然来.其实很多情况下都是纯凭直觉考虑到的数个思维方向,这种直觉是需要大量的练习来得到的,没有那么多“为什 ...
- mybatis自动生成代码
使用maven集成mybatis-generator插件生成Mybatis的实体类,DAO接口和Map映射文件 本例中,使用的是mysql数据库 前提:表已经建好 mybatis框架的jar包,数据 ...
- VMWare虚拟机提供的桥接、nat和主机模式的区别
虚拟机网络模式 无论是vmware,virtual box,virtual pc等虚拟机软件,一般来说,虚拟机有三种网络模式: 1.桥接 2.NAT 3.Host-Only 哪一种网络是适合自己的虚拟 ...
- openwrt刷机后配置PPPOE上网方法
参考下帖13#的方式: 如何编辑配置openwrt,来实现pppoe拨号上网? 但其中有一句代码有错误: option 'peerdns' '0',其中需将‘0’改为‘1’
- 【转】一个DIV+CSS代码布局的简单导航条
原文地址:http://www.divcss5.com/shili/s731.shtml 简单的DIV CSS代码布局实现导航条 一个蓝色主题的导航条布局案例,本CSS小实例,采用DIV CSS实现. ...