假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的 贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个 顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小 会场数。)
输入格式:
第一行有 1 个正整数k,表示有 k个待安排的活动。 接下来的 k行中,每行有 2个正整数,分别表示 k个待安排的活动开始时间和结束时间。时间 以 0 点开始的分钟计。
输出格式:
输出最少会场数。
输入样例:
5
1 23
12 28
25 35
27 80
36 50
输出样例:
在这里给出相应的输出。例如:
3
代码如下,需要解释的部分已经注释了
```java
import java.io.BufferedInputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;
class party implements Comparable<party> {
public int begin, end;
public party(int begin, int end) {
super();
this.begin = begin;
this.end = end;
}
/*
* 一定要按照开始时间进行排序 例如结束时间都为40,由于没有对开始时间排序,所以是乱序的,假设分别为33、13、14
* 上一个会场的结束时间为10,那么此时循环先让开始时间为33的会议衔接上一个会场而不是开始时间为13的会议
* 一个空余时间为23,另一个是空余时间为3,显然我们要空余时间短的,这才符合贪心策略(贪!)
*/
@Override
public int compareTo(party o) {
// TODO Auto-generated method stub
return this.begin - o.begin;
}
}
public class Main {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner in = new Scanner(new BufferedInputStream(System.in));
int k = in.nextInt();
LinkedList<party> l = new LinkedList<party>();
for (int i = 0; i < k; i++) {
int b = in.nextInt();
int e = in.nextInt();
l.add(new party(b, e));
}
// 按照开始时间进行升序排序
Collections.sort(l);
int times = 0;
int temp = 0;
while (!l.isEmpty()) {
temp = l.getFirst().end;// 获取队列的第一个元素的结束时间
l.removeFirst();// 再将它从队列中移除因为它已经没有用了
times++;/*
* 因为这场会议终将是要占据一个会场的,所以先开辟一个,
* 如果后面会场的开始时间大于该场的结束时间,那就继续使用这个会场,
* 否则这个会场只为这一个活动开辟
*/
for (int j = 0; j < l.size(); j++) {// 遍历移除后的会场
if (temp <= l.get(j).begin) {// 判断能不能和上面移除后的会议共用会场
temp = l.get(j).end;// 如果可以,更新结束时间,这一步很关键
l.remove(j);// 移除
j--;/*
* 这一步要好好解释一下, 假如说移除的这个元素位置是在3号,那么他后面元素x的位置为4号,
* 因为他已经被移除走了,元素x的位置现在就变成了3号,所以为了能够遍历到元素x,需要将j--
*/
}
}
}
System.out.println(times);
}
}
上面这个方法是自己想出来的,有些复杂。
下面这个是非常简洁的写法,具体思路就是,先将开始时间和结束时间都按升序排序,然后再遍历开始时间,如果某个会议i的开始时间小于某个会议j的结束时间,那么该会议i就要开辟一个会场,否则,就可以继续使用会议j用过的会场,这个想法很巧妙,可以自己在纸上模拟一下过程
import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(new BufferedInputStream(System.in));
int k=in.nextInt();
int[] begin=new int[k];
int[] end=new int[k];
for(int i=0;i<k;i++) {
begin[i]=in.nextInt();
end[i]=in.nextInt();
}
//两个都按升序排序
Arrays.sort(begin);
Arrays.sort(end);
int times=0;
int j=0;
for(int i=0;i<begin.length;i++) {
if(begin[i]<end[j])
times++;
else
j++;
}
System.out.println(times);
}
}
如果对你有帮助的话,记得点赞或者收藏嗷(: