题目
克里森是一名赏金猎人,他平时需要完成一些任务赚钱。最近他收到了一批任务,但是受到时间的限制,他只能完成其中一部分。
具体来说就是有n个任务,每个任务用l, r, w来表示任务开始的时间l,结束的时间r和完成任务获得的金钱。
克里森是个贪心的人,他想知道自己在任务不冲突的情况下最多获得多少金钱。
测试数据
// test data
8
1 4 5
3 5 1
0 6 8
4 7 4
3 8 6
5 9 3
6 10 2
8 11 4
代码
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 任务数
int[][] task = new int[n][3];
for (int i = 0; i < n; i++) {
task[i][0] = sc.nextInt(); // 开始
task[i][1] = sc.nextInt(); // 结束
task[i][2] = sc.nextInt(); // 收益
}
int rs = optMoney(task, n);
System.out.println(rs);
}
public static int optMoney(int[][] task,int n) {
//按照结束时间升序排序
Arrays.sort(task, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
int[] opt = new int[n+1];
opt[0] = 0; // 存0
opt[1] = task[0][2];
for (int i = 2; i <= n; i++) {
int opt_index = 0;
for (int j = i-1; j > 0; j--) {
// 计算对于当前任务,最近可以完成的上一个任务的下标是什么
// 即之前任务结束时间小于等于当前任务开始时间
// 求对于选择做当前任务,再加上前一个可以做的任务的最大收益,返回opt[j]+task[i][2]
if (task[j-1][1] <= task[i-1][0]) {
opt_index = j;
break;
}
}
opt[i] = Math.max(opt[i-1], opt[opt_index]+task[i-1][2]);
}
// for (int i = 0; i < n+1; i++) {
// System.out.println(opt[i]);
// }
return opt[n];
}
}
参考:时间最大化收益.