本题出自力扣题库第1043题。题面大意如下:
给定一个整数数组arr,将该数组分隔为长度最多为k的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。 返回将数组分隔变换后能够得到的元素最大和。
示例:
输入:arr = [1,15,7,9,2,5,10], k = 3
输出:84
解释:
因为 k=3 可以分隔成 [1,15,7] [9] [2,5,10],结果为 [15,15,15,9,10,10,10],和为 84,是该数组所有分隔变换后元素总和最大的。
题解:
这是一个一维数组的基本DP应用,从题意出发可以很容易地得到以下的DP表达式:
F(i) = max (
max(arr[i]) * 1 + F(i + 1)
max(arr[i] + 1) * 2 + F(i + 2)
max(arr[i] + 2) * 3 + F(i + 3)
...
max(arr[i] + k - 1) * k + F(i + k)
)
这里i是数组下标,F(i)返回的是从i开始的子数组按题面要求分割后的最大元素和,我们使用一维DP数组及一个单层的循环,按照数组下标从大到小依次计算DP数组中各个元素的值,循环完成后,DP[0]中的数值就是问题的答案。
Java代码如下:
class Solution {
public int maxSumAfterPartitioning(int[] arr, int k) {
int N = arr.length;
int[] dp = new int[N + 1];
for (int i = N - 1; i >= 0; i--) {
int max = arr[i] + dp[i + 1];
int maxElement = arr[i];
for (int j = 2; (j <= k) && (i + j - 1 < N) ; j++) {
maxElement = Math.max(maxElement, arr[i + j - 1]);
int sum = maxElement * j + dp[i + j];
max = Math.max(max, sum);
}
dp[i] = max;
}
return dp[0];
}
}