贪心后悔法:
总的来说就是贪心+优先队列;题目大概都是有两个限制条件,然后给一个排序,另一个条件进行判断队列大小;
优先队列的底层就是一个小根堆,插入数据的时候就会自动调整堆,总是让最小的元素放在前面。
(哪个放在前面却决于你自己定义的Comparator比较器)
优先级队列 PriorityQueue
PriorityQueue 类在 Java 1.5 中引入。
PriorityQueue 是基于优先堆的一个无界队列,这个优先队列中的元素可以默认自然排序或者通过提供的 Comparator 在队列实例化的时排序。
PriorityQueue 不允许空值,而且不支持 non-comparable(不可比较)的对象,比如用户自定义的类。优先队列要求使用 Java Comparable 和 Comparator 接口给对象排序,并且在排序时会按照优先级处理其中的元素。
PriorityQueue 的大小是不受限制的,但在创建时可以指定初始大小。当我们向优先队列增加元素的时候,队列大小会自动增加。
PriorityQueue 是非线程安全的,所以 Java 提供了 PriorityBlockingQueue(实现 BlockingQueue接口)用于Java 多线程环境。
后悔法的例题

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
/**
* @author SJ
* @date 2020/10/31
*/
public class ActivityArrange {
public static void main(String[] args) {
//建测试数据
Activity.newActivities();
// Activity.print();
//开始安排
Queue<Activity> activities = arrangeActivities();
int totalProfit = 0;
for (Activity activity : activities) {
totalProfit += activity.profit;
System.out.println(activity.toString());
}
System.out.println("能获得的最大利润为:" + totalProfit);
}
public static class Activity {
public int ddl;
public int profit;
public static Queue<Activity> activities = new PriorityQueue<>(new Comparator<Activity>() {
@Override
public int compare(Activity o1, Activity o2) {
return o1.ddl - o2.ddl;
}
});
@Override
public String toString() {
return "Activity{" +
"ddl=" + ddl +
", profit=" + profit +
'}';
}
public Activity(int ddl, int profit) {
this.ddl = ddl;
this.profit = profit;
}
public static void newActivities() {
activities.add(new Activity(2, 10));
activities.add(new Activity(1, 5));
activities.add(new Activity(1, 7));
}
//测试队列
public static void print() {
for (Activity activity : activities) {
System.out.println(activity);
}
}
}
public static Queue<Activity> arrangeActivities() {
Queue<Activity> temp = Activity.activities;
Comparator<Activity> activityComparator = (o1, o2) -> o1.ddl - o2.ddl;
//temp里面队头放截至是建最前的,从前往后往arrange里面安排
//队头放截止时间最晚的。
Queue<Activity> arrange = new PriorityQueue<>(activityComparator.reversed());
while (!temp.isEmpty()) {
Activity currentActivity = temp.poll();//取出队头元素并删除
if (!arrange.isEmpty()) {
//ddl相同的,如果即将进队的活动的利润比当前队列里活动的利润大,队列里那个活动删掉,把新的活动加进去。
if (arrange.peek().ddl == currentActivity.ddl && arrange.peek().profit < currentActivity.profit) {
arrange.poll();
arrange.add(currentActivity);
} else
arrange.add(currentActivity);
} else {
arrange.add(currentActivity);
}
// temp.poll();
}
return arrange;
}
}
测试结果:
"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe"...
Activity{ddl=2, profit=10}
Activity{ddl=1, profit=7}
能获得的最大利润为:17
Process finished with exit code 0