第一行依次给出正整数n,m,单空格切分;(n <= 10000, m <= 10000, m <= n)
第二行依次给出n个正整数单空格切分A1,A2,… ,An (Ai <= 10000)
分割权重的最小值
5 3 1 4 2 3 5
5
分割成 1 4 | 2 3 | 5 的时候,3段的权重都是5,得到分割权重的最小值。
// 结果在(max(nums),sum(nums))之间,使用二分查找
// 以[7,2,5,10,8]举例,开始假设只有一个子数组,set=1
// 第一个 mid = (10+32)/2=21, 然后把数字一个一个塞进去
// 先塞7, 7<21, 7+2<21, 7+2+5<21, 直到 7+2+5+10>21
// 意味着一个数组放不下, set+1=2, 然后把后面的塞完
// 如果比m大说明我们开的子数组太多, 也就意味值我们数组容量(mid)太小
// 所以我们就从[22,32]区间中找, 否则在[10,21]中找
import java.util.Scanner;
public class Main {
public static int splitArray(int[] nums, int m) {
int max = Integer.MIN_VALUE, sum = 0;
for (int i : nums){
sum += i;
max = Math.max(max,i);
}
int left = max, right = sum;
int mid, set, cur;
while(left < right){
mid = (left+right)/2;
// m 是子数组数,不是cut数
set = 1;
cur = 0;
for(int i : nums){
if(cur+i > mid){
set++;
cur = 0;
}
cur+= i;
}
if(set > m) left = mid + 1;
else right = mid;
}
return left;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] nums = new int[n];
for (int i=0; i<n; i++){
nums[i] = sc.nextInt();
}
System.out.print(splitArray(nums,m));
}
}