NJU-高級算法-時間與收益

Description

Given a set of n jobs where each job i has a deadline and profit associated to it. Each job takes 1 unit of time to complete and onlyone job can be scheduled at a time. We earn the profit if and only if the job is completed by its deadline. The task is to find the maximum profit and the number of jobs done.

Input

The first line of input contains an integer T denoting the number of test cases.Each test case consist of an integer N denoting the number of jobs and the next line consist of Job id, Deadline and the Profit associated to that Job.

Constraints:

1<=T<=100,1<=N<=100,1<=Deadline<=100,1<=Profit<=500

Output

Output the number of jobs done and the maximum profit.

Sample Input

2
4
1 4 20 2 1 10 3 1 40 4 1 30
5
1 2 100 2 1 19 3 2 27 4 1 25 5 1 15

Sample Output

2 60
2 127

 

思路

貪心

開一個長度爲maxDeadline+1的數組,實際從下標爲1開始存數據,days[i]表示第i天的收益.
將所有工作按profit從大到小排序,從profit值最大的工作開始安排,並儘量將其安排在其deadline那天完成(即儘量排在最後完成),以讓出更多時間給deadline更早的工作.
舉例,如當前遍歷到的工作profit爲40,deadline爲3,則內層循環j從3開始往前遍歷,若days[3]爲空,則直接將該工作的profit賦值給days[3],若days[3]已被佔用(一定是被profit更大的工作佔用),那麼就繼續考察days[2], days[1]找到第一個能佔用的時間點,若days[2],days[1]都被佔用則當前工作無法被加入job sequence.

 

代碼

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int cases = Integer.parseInt(sc.nextLine());
        while (cases-- > 0) {
            int n = Integer.parseInt(sc.nextLine());
            int[] input = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
            int[] deadline = new int[n];
            int[] profit = new int[n];

            for (int i = 0; i < input.length; i += 3) {
                // input[i]爲工作號,input[i]-1爲對應工作的數組下標
                deadline[input[i] - 1] = input[i + 1];
                profit[input[i] - 1] = input[i + 2];
            }
            int sum = 0;
            int num = 0;

            int[] res = maxProfit(deadline, profit);
            num = res[0];
            sum = res[1];
            System.out.println(num + " " + sum);

        }
        sc.close();
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static int[] maxProfit(int deadLine[], int profit[]) {
        int len = profit.length;
        int maxDeadline = deadLine[0];
        int maxProfit = 0;
        int count = 0;

        // 按profit排序,profit大的排在前面,若profit相等則deadline大的放在前面
        for (int i = 0; i < len; i++) {
            for (int j = i + 1; j < len; j++) {
                if (profit[i] < profit[j]) {
                    swap(profit, i, j);
                    swap(deadLine, i, j);
                } else if (profit[i] == profit[j]) {
                    if (deadLine[i] < deadLine[j]) {
                        swap(profit, i, j);
                        swap(deadLine, i, j);
                    }
                }
            }
        }
        // 計算deadline最大值
        for (int i = 0; i < len; i++) {
            maxDeadline = deadLine[i] > maxDeadline ? deadLine[i] : maxDeadline;
        }

        // 開一個長度爲maxDeadline+1的數組,實際從下標爲1開始存數據
        // days[i]表示第i天所做的工作的profit
        int days[] = new int[maxDeadline + 1];
        for (int i = 0; i < len; i++) {
            for (int j = deadLine[i]; j > 0; j--) {
                if (days[j] == 0) {
                    days[j] = profit[i];
                    count++;
                    break;
                }
            }
        }

        for (int i = 0; i < days.length; i++) {
            maxProfit += days[i];
        }
        int[] res = new int[2];
        res[0] = count;
        res[1] = maxProfit;
        return res;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章