顺丰笔试-赏金猎人2020-08-20(参考时间最大利益)

目录

  • 题目
  • 测试数据
  • 代码

题目

克里森是一名赏金猎人,他平时需要完成一些任务赚钱。最近他收到了一批任务,但是受到时间的限制,他只能完成其中一部分。
具体来说就是有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];
    }
}

参考:时间最大化收益.

你可能感兴趣的:(Java后端,java)