NJU-高级算法-订单问题

Description

Rahul and Ankit are the only two waiters in Royal Restaurant. Today, the restaurant received N orders. The amount of tips may differ when handled by different waiters, if Rahul takes the ith order, he would be tipped Ai rupees and if Ankit takes this order, the tip would be Bi rupees.
In order to maximize the total tip value they decided to distribute the order among themselves. One order will be handled by one person only. Also, due to time constraints Rahul cannot take more than X orders and Ankit cannot take more than Y orders. It is guaranteed that X + Y is greater than or equal to N, which means that all the orders can be handled by either Rahul or Ankit. Find out the maximum possible amount of total tip money after processing all the orders.

Input:

•    The first line contains one integer, number of test cases.
•    The second line contains three integers N, X, Y.
•    The third line contains N integers. The ith integer represents Ai.
•    The fourth line contains N integers. The ith integer represents Bi.

Output:

Print a single integer representing the maximum tip money they would receive.

Constraints:

1 ≤ N ≤ 105
1 ≤ X, Y ≤ N; X + Y ≥ N
1 ≤ Ai, Bi ≤ 104

Sample Input:

2
5 3 3
1 2 3 4 5
5 4 3 2 1
8 4 4
1 4 3 2 7 5 9 6 
1 2 3 6 5 4 9 8

Sample Output:

21
43

 

思路

动态规划

1.确定状态

对于n个任务,服务员A能接受的最大工作数量为x,服务员B能接受的最大工作数量为y,设一三维矩阵dp[n+1][x+1][y+1],dp[i][j][k]表示第i个任务由服务员A或服务员B做所能获得的最大收益。

dp[i][j][k] = max(dp[i - 1][j - 1][k] + A[i - 1], dp[i-1][j][k-1] + B[i-1])

dp[i - 1][j - 1][k] + A[i - 1]表示由A来做第i个任务,那么就占用A的第j个空闲工作时间完成第i个任务,而B的第k个空闲工作时间在该情况下未被占用,dp[i][j][k]就等于其子问题dp[i-1][j-1][k]所代表的最大收益加上由A做第i个任务的收益.

dp[i - 1][j ][k-1] + B[i - 1]表示由B来做第i个任务,那么就占用B的第k个空闲工作时间完成第i个任务,而A的第j个空闲工作时间在该情况下未被占用,dp[i][j][k]就等于其子问题dp[i-1][j][k-1]所代表的最大收益加上由B做第i个任务的收益.

2.初始化

dp[1..n][1...x][0]表示只考虑让A做任务的情况,dp[i][j][0]表示,第i个任务由Rahul在其第j个工作空档期做所能取得的收益,其值等于其子问题dp[i - 1][j - 1][0]所代表的最大收益加上由A完成第i个任务的收益.

dp[1..n][1...x][0]表示只考虑让A做任务的情况,dp[i][j][0]表示,第i个任务由Rahul在其第j个工作空档期做所能取得的收益,其值等于其子问题dp[i - 1][j - 1][0]所代表的最大收益加上由A完成第i个任务的收益.

3.边界情况

dp[n][x][y]即为该题的解

4.计算顺序

i从1到n,j从1到x,k从1到y

 

代码

import java.util.*;

public class Main {

    private static int maxTip(int[] A, int[] B, int n, int x, int y) {
        int[][][] dp = new int[n + 1][x + 1][y + 1];

        // 初始化,考察各个任务仅由一人做取得的最大收益
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= x; j++) {
                // dp[i][j][0]表示,第i个任务仅由Rahul在其第j个工作空档期做所能取得的收益
                // 该值等于第i-1个任务仅由Rahul在其第j-1个工作空档期做所能取得的最大收益+Rahul做第i个任务的收益
                dp[i][j][0] = dp[i - 1][j - 1][0] + A[i - 1];
            }
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= y; j++) {
                dp[i][0][j] = dp[i - 1][0][j - 1] + B[i - 1];
            }
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= x; j++) {
                for (int k = 1; k <= y; k++) {
                    int maxTipOfA = dp[i - 1][j - 1][k] + A[i - 1];
                    int maxTipOfB = dp[i - 1][j][k - 1] + B[i - 1];

                    dp[i][j][k] = Math.max(maxTipOfA, maxTipOfB);
                }
            }
        }

        return dp[n][x][y];
    }

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

            int[] A = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
            int[] B = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();

            int res = maxTip(A, B, n, x, y);
            System.out.println(res);
        }
        sc.close();
    }
}

 

你可能感兴趣的:(NJU-高级算法)