/*
* @lc app=leetcode id=410 lang=cpp
*
* [410] Split Array Largest Sum
*/
class Solution {
public:
int splitArray(vector<int>& nums, int m) {
const auto check = [](vector<int>& weights, long mid) {
long sum = 0, c = 1;
for (int w : weights) {
if (sum + w > mid) {
sum = 0;
++c;
}
sum += w;
}
return c;
};
long start = 1, end = 1;
for (int w : nums) {
start = max(start, (long) w);
end += w;
}
while (start < end) {
long mid = start + (end - start) / 2;
if (m < check(nums, mid)) {
start = mid + 1;
} else {
end = mid;
}
}
return start;
}
};
/*
* @lc app=leetcode id=410 lang=cpp
*
* [410] Split Array Largest Sum
*
* https://leetcode.com/problems/split-array-largest-sum/description/
*
* algorithms
* Hard (42.82%)
* Likes: 954
* Dislikes: 53
* Total Accepted: 53.5K
* Total Submissions: 124.8K
* Testcase Example: '[7,2,5,10,8]\n2'
*
* 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.
*
*
*/
class Solution {
public:
int splitArray(vector<int>& nums, int m) {
const int N = nums.size();
vector<long> sums(N);
sums[0] = nums[0];
for (int j = 1; j < N; ++j) {
sums[j] = sums[j - 1] + nums[j];
}
vector<vector<long>> dp(m + 1, vector<long>(N, INT_MAX));
for (int j = 0; j < N; ++j) dp[1][j] = sums[j];
for (int i = 2; i <= m; ++i) {
for (int j = 0; j < N; ++j) {
for (int k = 0; k < j; ++k) {
dp[i][j] = min(dp[i][j], max(dp[i - 1][k], sums[j] - sums[k]));
}
}
}
return dp[m][N - 1];
}
};