We'll search for the optimal value using binary search. Obviously, this value cannot be less than (since the elements of the array are positive integers) and cannot exceed the sum of all elements in the array. Set the boundaries: left = 1, right = sum of all array elements. The answer is guaranteed to lie within the range [left; right].
Now consider a helper subproblem: is it possible to split the array into subarrays such that the maximum sum among all subarrays does not exceed a given value s_0? If the array contains at least one element greater than s_0, such a split is impossible. Otherwise, we sequentially form subarrays so that the sum of each does not exceed s_0. If the total number of resulting subarrays is no more than , then such a split is considered possible.
Example
In the second example, let us consider possible ways to split the array into subarrays for different values of s_0:
Algorithm implementation
Define a constant MAX = 10^6 and an array .
#define MAX 1000000
int m[MAX];The function f returns if the array can be split into subarrays such that the maximum sum among all subarrays does not exceed the given value s_0.
int f(long long s0)
{
long long sum = 0;
int cnt = 1;
for (int i = 0; i < n; i++)
{If any element of the array is greater than s_0, such a split is not possible.
if (m[i] > s0) return 0;Compute the sum of the current subarray.
sum += m[i];As soon as this sum exceeds the value s_0, increase the subarray counter by and start accumulating the sum for the next subarray.
if (sum > s0)
{
sum = m[i];
cnt++;
}
}If the array can be split into no more than subarrays, then it can also be split into exactly subarrays (since k \le n).
if (cnt <= k) return 1;
return 0;
}The main part of the program. Read the input data. In the variable , compute the sum of all elements in the array.
scanf("%d %d", &n, &k);
left = 1; right = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &m[i]);
right += m[i];
}The desired minimum value of the maximum subarray sum lies within the range [left; right]. Perform a binary search on this interval.
while (left < right)
{
mid = (left + right) / 2;
if (f(mid) == 1)
right = mid;
else
left = mid + 1;
}Print the answer.
printf("%lld\n", left);