类似题目:
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。
输入格式:
第一行有 1 个正整数k,表示有 k个待安排的活动。
接下来的 k行中,每行有 2个正整数,分别表示 k个待安排的活动开始时间和结束时间。时间以 0 点开始的分钟计。
输出格式:
输出最少会场数
题目分析:把每场会议的时间段映射到枢轴上的一段区间,那么求解最小的会议场数就转换成了求解数轴上所有区间里面,有交错的区间里面交错数最多的那个,如下图所示,最多为3,也可以理解为用一条直线去平移,最多的交点数。怎么贪心呢?我们将每个区间的起点与终点分别赋予值1与-1,然后按照端点位置排序,位置相同的按照值排序,最后去遍历每个区间,并且累加值,同时更新最大值,累加其实就是遇到起点就加(每一个起点都会与直线产生一个交点),遇到终点就减(为了求出最大的交点,需将移动过的区间去掉),这样就能求出最多的交点数了。
代码:
import java.util.*;
public class Main{
static Scanner in = new Scanner(System.in);
static int ans = 0;
public static void main(String[] args) {
int n = in.nextInt();
List<Node> st = new ArrayList<>();
int s,e;
for (int i = 0; i < n; i++) {
s = in.nextInt();
e = in.nextInt();
st.add(new Node(s,1));
st.add(new Node(e,-1));
}
Collections.sort(st,(o1,o2)->(o1.d==o2.d?o1.v-o2.v:o1.d-o2.d));
int ans = Integer.MIN_VALUE;
int cur = 0;
for (int i = 0; i < st.size(); i++) {
cur += st.get(i).v;
ans = Math.max(ans,cur);
}
System.out.println(ans);
}
}
class Node{
int d,v;
Node(int d,int v){
this.d = d;//端点
this.v = v;//端点值
}
}
另一种写法
public class Main {
static Scanner in = new Scanner(System.in);
static int ans = 0;
static int[] beginn = new int[10005];//存开始时间
static int[] endd = new int[10005];//存结束时间
public static void main(String[] args) {
int n = in.nextInt();
int cnt = 0;//需要的最少会场数
for (int i = 0; i < n; i++) {
beginn[i] = in.nextInt();
endd[i] = in.nextInt();
}
//按开始时间升序排列
Arrays.sort(beginn, 0, n);
//按结束时间升序排列
Arrays.sort(endd, 0, n);
int j = 0;
for (int i = 0; i < n; i++) {
if (beginn[i] < endd[j])
cnt++;
else
j++;
}
System.out.println(cnt);
}
}
猿辅导笔试第一题基本就是这个题的路子,给出每个课的上课时间段,求解最多一心几用,就是求解最多的交错区间数目吧