问题描述:
有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与,即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。
样例:
输入
n=5
s={1,2,4,6,8}
T={3,5,7,9,10}
输出
3(选择工作1, 3, 5)
分析:这一题用到贪心算法的思想,就是每次选取结束时间最早的,从局部上达到最优,实际上整体也是最优的。
我们需要对数据进行排序,排序的目的是使结束时间短的排在前面.这一点我们可以利用Java中的对象进行封装,然后利用Arrays.sort进行排序,但是我们需要定义排序规则,开始时间相同的时候,比较结束时间。
排序前:
排序后:
这样进行一次遍历,每次将上一个结束时间和下一个的开始时间进行比较,如果下一个的开始时间大于上一个的结束时间,那么次数就加1,例如:第一次结束时间是2,但是下一个开始时间是1,这说明两个时间重叠了,我们就跳过,继续进行遍历,直到循环结束。
代码如下:
import java.util.Arrays;
import java.util.Scanner;
public class Job implements Comparable<Job>{
int s;//开始时间
int t;//结束时间
public Job(int s, int t) {
this.s = s;
this.t = t;
}
@Override
public int compareTo(Job other) {//自定义比较规则,返回值为负数,就是升序排序
int x=this.t-other.t;
if (x==0)return this.s-other.s;
else return x;
}
}
class Text1{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[] s=new int[n];
int[] t=new int[n];
Job[] jobs=new Job[n];
for (int i = 0; i < n; i++) {
s[i]=sc.nextInt();
}
for (int i = 0; i < n; i++) {
t[i]=sc.nextInt();
}
for (int i = 0; i < n; i++) {
jobs[i]=new Job(s[i],t[i]);
}
Arrays.sort(jobs);
int res=f(n,jobs);
System.out.println(res);
}
private static int f(int n,Job[] jobs){
int cnt=1;
int y=jobs[0].t;
for (int i = 1; i < n; i++) {
if (jobs[i].s>y){
cnt++;
y=jobs[i].t;
}
}
return cnt;
}
}