本文为最近做过的一道编程笔试题,代码实现方式多种多样,此处本人提供的代码可以获得正确解,仅供大家参考。
一、题目描述
题目描述:
Mike在一家律师事务所工作,他的老板Harvey分配给他N个新案件,每个案件都有自己的利益值。Harvey要求他将连续案件分组,让所有组的利益值总额最大化。一组的利益值由该组内案件个别利益值的最大与最小值之间的差额决定。Harvey知道这对Mike来说将是一项很轻松的任务,因此,他要求Mike记住一点,如果一组内只有单个案件,其利益值将视为零。
输入描述:
- 输入1: 整数N,代表案件数量
- 输入2: 整数数组A,代表案件的利益值
输出描述:
- 返回所有组中的最大利益值。
示例:
- 输入
5 1 3 2 4 5
- 输出
5
说明:
有5个案件,我们按照以下顺序获得案件的最大利益值:
- 组1: {1,3},最大利益值 = 2 (3-1)。
- 组2: {2,4,5}, 最大利益值 = 3 (5-2)
利益值总额 = 2+3 = 5。因此,返回 5作为输出结果。
二、实现代码程序
解题思路:
根据Harvey的要求,Mike需要将N个新案件分组,使得每个组内案件个别利益值的最大与最小值之间的差额最大化。为了解决这个问题,可以使用动态规划的方法。
- 我们可以定义一个数组dp,其中dp[i]表示前i个案件能够得到的最大利益值总额。对于每个案件i,我们需要找到它所属的组,使得该组内案件个别利益值的最大与最小值之间的差额最大化。
- 对于第i个案件,我们可以选择将其与前面的某个案件j放在同一组内,或者将其作为单独的一组。如果将其与前面的案件j放在同一组内,那么该组的利益值总额为dp[j-1]加上该组内案件个别利益值的最大与最小值之间的差额。如果将其作为单独的一组,那么该组的利益值总额为0。
- 因此,我们可以得到状态转移方程:
dp[i] = max(dp[j-1] + max_val - min_val, dp[i-1])
其中,max_val表示第j到第i个案件中的最大利益值,min_val表示第j到第i个案件中的最小利益值。 - 最终,dp[N]即为所求的结果,表示前N个案件能够得到的最大利益值总额。
通过动态规划的方法,Mike可以根据这个方程计算出最大利益值总额,并将案件分组,使得利益值总额最大化。
代码实现如下:
import java.util.*;
public class Main {
public static int maximizeProfit(int[] profits) {
int n = profits.length;
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
int maxVal = profits[i - 1];
int minVal = profits[i - 1];
dp[i] = dp[i - 1]; // Case where current case forms a single group
for (int j = i - 1; j >= 1; j--) {
maxVal = Math.max(maxVal, profits[j - 1]);
minVal = Math.min(minVal, profits[j - 1]);
dp[i] = Math.max(dp[i], dp[j - 1] + maxVal - minVal);
}
}
return dp[n];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int[] profits = new int[N];
for(int i = 0; i < N; ++i){
profits[i] = sc.nextInt();
}
int result = maximizeProfit(profits);
System.out.println(result);
}
}
三、测试结果截图
输入:
5
1 3 2 4 5
输出结果如下: