Noes:
This question is said to be a classical dp question, but I do not think I had seen this before.
Anyway, the method used here is the so-called "local-global" maximum algorithm.
local[i][j]: represents the maximum value achieved using the first i elements with j non-overlapping groups and ending with the ith element;
global[i][j]: represents the maximum value achieved using the first i elements with j non-overlapping groups and not necessarily ending with the ith element;
local[j][j] = max (global[i-1][j-1], local[i-1][j]) + nums[i]
The local[i][j] must ends with the ith element, so we need to add it. The ith element can form a group (sub-array) by itself; or it can joins the previous group, which corresponds to the first and the second terms;
global[i][j] = max(global[i-1][j], local[i][j])
For global[i][j], we may or may not use the ith element. If used, it should be local[i][j]; otherwise it is global[i-1][j].
In addition, we need to pay attention to the initialization:
(1) When j > i, it is impossible to form j different non-overlapping groups. In this case, it can be initialized as INT_MIN;
(2) local[i][0] can be initialized as INT_MIN as well, since it is impossible to form this kind of condition;
(3) global[i][0] can be initialized as 0. We simply do no choose any element.
See the code below:
class Solution {
public:
/**
* @param nums: A list of integers
* @param k: An integer denote to find k non-overlapping subarrays
* @return: An integer denote the sum of max k non-overlapping subarrays
*/
int maxSubArray(vector<int> &nums, int k) {
// write your code here
int len = nums.size();
vector<vector<int>> local(len+1, vector<int>(k+1, INT_MIN)), global(len+1, vector<int>(k+1, INT_MIN));
//local[i][j]: the maximum sum of j non-overlapping subarrays ending with the ith elements;
//global[i][j]: the maximum sum of j no-voerlapping subarrays not necessary ending with the ith elements.
//local[i][j] = max(global[i-1][j-1], local[i-1][j]) + nums[i];
//global[i][j] = max(global[i-1][j], local[i][j]);
for(int i=0; i<=len; ++i) global[i][0] = 0;
for(int i=1; i<=len; ++i) {
for(int j=1; j<=min(k, i); ++j) {
local[i][j] = max(global[i-1][j-1], local[i-1][j]) + nums[i-1];
global[i][j] = max(global[i-1][j], local[i][j]);
}
}
return global[len][k];
}
};
No comments:
Post a Comment