Baseline Time Limit: 1 second Space Limit: 131072 KB Score: 80
Difficulty: Level 5 Algorithm Questions
Given an array of positive integers of length N, divide the N numbers into K groups without changing the order of the array elements. The sum of the elements in each group is S1, S2....Sk, respectively. How to group so that the maximum value among S1 to Sk is the smallest?
For example: 1 2 3 4 5 6 is divided into 3 groups, {1 2 3} {4 5} {6}, the element sum is 6, 9, 6, and the maximum value is 9. It can also be divided into {1 2 3 4} {5} {6}. The element sum is: 10 5 6, and the maximum value is 10. So the first solution is better. And the maximum value of the first scheme is the smallest among all the schemes. Output this minimum maximum value.
Input
Line 1: 2 numbers N, K, separated by spaces, N is the length of the array, and K is the number of groups to be divided into. (2 <= K < N <= 50000) Line 2 - N + 1: Array elements (1 <= A[i] <= 10^9)
Output
Output this minimum maximum value.
Input example
6 3123456
Output example
9
Idea: Dichotomous answer, the consecutive sum greater than the number in front of mid is a group, and finally the smallest and largest value is obtained.
Code:
#include <bits/stdc++.h> #define LL long long using namespace std; const int AX = 5e4+66; int a[AX]; int n , m; int fun( LL x ){ LL s = 0LL; int tot = 0; for( int i = 0; i < n ; i ++ ){ s += a[i]; if( s >= x ){ if( s > x ){ i--; } s = 0 ; to ++; } } if( s ) tot ++ ; return ( (tot <= m ) ? 1 : 0 ); } int main(){ ios_base::sync_with_stdio(false) ; cin >> n >> m; LL sum = 0LL; int maxn = -1; for( int i = 0 ; i < n ; i++ ){ cin >> a[i]; maxn = max( maxn , a[i] ); sum += a[i]; } LL l = maxn; LL r = sum; while( l <= r ){ LL mid = ( l + r ) >> 1; if( fun(mid) ){ r = mid - 1 ; }else{ l = mid + 1 ; } } cout << l << endl; return 0 ; }