问题分析:
这是第一个测试用例的草图,可以得出结论,每个任务只耗费1个时间单位,因此优先选择ddl大的任务,在ddl相同时优先选择profit高的那个。如本例中,先选择1号(因为它的deadline最长),获得效益20,再从ddl=1中选取效益最高的3号,获得效益40,即20+40=60。
算法思路:将所有存在的deadline按照递减顺序保存起来,将deadline与对应存在的效益列表建立映射关系。每次遍历时,都能确保是最大的 ddl,从效益列表取一个最大的效益出来,该列表剩余的效益继续存放到下一个ddl对应的效益列表中。
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class TimeAndProfit {
public static void main(String[]args) {
Scanner sc=new Scanner(System.in);
int testcase=sc.nextInt();
for(int i=0;i<testcase;i++) {
int n=sc.nextInt();
int[][] arr=new int[n][3];
Set<Integer> deadlines=new TreeSet<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
for(int l=0;l<n;l++) {
arr[l][0]=sc.nextInt();
arr[l][1]=sc.nextInt();
arr[l][2]=sc.nextInt();
deadlines.add(arr[l][1]);
}
List<Integer> deadlinesList=new ArrayList<>(deadlines);
Map<Integer,Queue<Integer>> map=new HashMap<>();
for(int l=0;l<n;l++) {
Queue<Integer> queue=map.get(arr[l][1]);
if(queue==null) {
queue=new PriorityQueue<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
}
queue.add(arr[l][2]);
map.put(arr[l][1], queue);
}
int profit=0,count=0;
int size=deadlines.size()-1;
for(int k=0;k<size;k++) {
Queue<Integer> queue=map.get(deadlinesList.get(k));
profit+=queue.poll();
count++;
Queue<Integer> next=map.get(deadlinesList.get(k+1));
while(!queue.isEmpty()) {
next.add(queue.poll());
}
}
profit+=map.get(deadlinesList.get(deadlines.size()-1)).poll();
count++;
System.out.println(count+" "+profit);
}
sc.close();
}
}