题目描述:
Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays.
Note:
If n is the length of array, assume the following constraints are satisfied:
1 ≤ n ≤ 1000
1 ≤ m ≤ min(50, n)
Examples:
Input: nums = [7,2,5,10,8] m = 2
Output: 18
Explanation: There are four ways to split nums into two subarrays. The
best way is to split it into [7,2,5] and [10,8], where the largest sum
among the two subarrays is only 18.
算法分析:
这道题被放在动态规划的Tag下..然后用常规的动态规划方法思考了挺久没能想到解法…
参考了一下Discussion….
主要思路是将使最大和最小化的问题转化为了查找一个最小的最大和。
先确定这个值的范围,比较明显,是[ max(nums[i]), sum(nums[i]) ]。
之后用二分查找的方法在这个范围里查找符合条件的最小值。对于查找过程中的每个值k,判断能否将nums[]分为小于m个组,使得每组的和小于k。
详细代码:
class Solution {
public:
int splitArray(vector<int>& nums, int m) {
int max = 0;
unsigned long long sum = 0;
for (int i = 0; i < nums.size(); i++) {
sum += nums[i];
max = nums[i] > max ? nums[i] : max;
}
unsigned long long left = max, right = sum, mid;
while (left < right) {
mid = left + (right-left)/2;
if (splitArray_k(nums, m, mid)) {
right = mid;
} else {
left = mid+1;
}
}
return left;
}
private:
bool splitArray_k(vector<int>& nums, int m, unsigned long long k) {
unsigned long long sum = 0;
for (int i = 0; i < nums.size(); i++) {
if (k >= sum + nums[i]) {
sum += nums[i];
} else {
if (m == 1) return false;
sum = nums[i];
m--;
}
}
return true;
}
};
提交结果:
27 / 27 test cases passed.
Status: Accepted
Runtime: 3 ms
Your runtime beats 41.58 % of cpp submissions.