AcWing 906. 区间分组 (贪心)
程序员文章站
2022-06-04 15:45:04
...
这两天累死了,准备结课的各种考试和项目。
题目
这道贪心的题目,是这么个意思
所以答案是三,就是同一个区间不能有重复的元素,包括端点。
考虑排序左端点后用优先队列表示每个区间,最后输出优先队列大小即可。
另外我要再看一下排序器的用法, 时间长了不用又要忘了。
这里给出AcWing一位同学的题解,表达能力比我好很多:
算法分析
1、将所有区间按左端点从小到大排序
2、从前往后枚举每个区间,判断能否将其放到某个现有的组中,即是否存在区间的的左端点L > 所有组中右端点的最小值
如果不存在这样的组,则开新组,然后再将其放进组中
如果存在这样的组,则将其放在符合条件的组中,并更新当前组的右端点的值
3、为了不用每次选择组时都遍历所有组,可以通过小根堆来维护所有组中的尾端
证明:
1、按照上述存放,一定是一种合法的方案,则Ans <= cnt
2、由于分了cnt个组,则说明一定存在cnt个区间含有公共点,则一定至少开cnt个组,则Ans >= cnt
综合1、2可推出Ans == cnt
时间复杂度 O(nlogn)
作者:小呆呆
链接:https://www.acwing.com/solution/acwing/content/5898/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Code
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.PriorityQueue;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(System.out);
static int N = 100010;
static ArrayList<Pair> al = new ArrayList<>();
static PriorityQueue<Integer> q = new PriorityQueue<>();
public static void main(String[] args) throws Exception {
String[] s = br.readLine().split(" ");
int n = Integer.parseInt(s[0]);
for (int i = 0; i < n; i++) {
s = br.readLine().split(" ");
al.add(new Pair(Integer.parseInt(s[0]), Integer.parseInt(s[1])));
}
Collections.sort(al);
for (Pair p : al) {
if (q.isEmpty() || q.peek() >= p.getFront()) q.offer(p.getSecond());
else {
q.poll();
q.offer(p.getSecond());
}
}
pw.println(q.size());
pw.flush();
pw.close();
br.close();
}
}
class Pair implements Comparable<Pair> {
int front;
int second;
public Pair(int front, int second) {
this.front = front;
this.second = second;
}
public int getFront() {
return front;
}
public void setFront(int front) {
this.front = front;
}
public int getSecond() {
return second;
}
public void setSecond(int second) {
this.second = second;
}
@Override
public int compareTo(Pair o) {
return front - o.getFront();
}
}
下一篇: 45. Jump Game II