题意:给出n个数字,要求分成连续的m段,使每段的和的最大值最小
思路:我们可以枚举这个最小的最大值,假如不满足就向右二分,满足就向左二分
那么判断条件是什么呢?
显然是按这个我们枚举的mid(就是我们在枚举的最大值)进行划分,看看会分出多少个区间段来
假如大于,则不满足,小于等于则满足
但是,有一种情况需要注意:就是按我代码里的做法,当出现一个数就大于我们枚举的最大值的时候
就会有问题,所有需要特判
代码如下
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 const int inf=0x3f3f3f3f; 5 int a[maxn]; 6 int n,limit; 7 int check(int mid) 8 { 9 int sum=0; 10 int cnt=0; 11 for(int i=1;i<=n;i++){ 12 sum+=a[i]; 13 if(sum>mid){ //假如总和大于我们枚举的最大权值了,则区间段数++ 14 cnt++; //然后从当前位置继续枚举 15 sum=a[i]; 16 if(sum>mid) return 0; //这是单个就大于枚举最大权值的情况 17 } 18 } 19 if(sum) cnt++; 20 if(cnt>limit) return 0; 21 else return 1; 22 } 23 int main() 24 { 25 scanf("%d%d",&n,&limit); 26 for(int i=1;i<=n;i++){ 27 scanf("%d",&a[i]); 28 } 29 int L=0; 30 int R=inf; //先定义范围 31 int ans; 32 while(L<=R){ 33 int mid=L+R>>1; 34 if(check(mid)){ 35 R=mid-1; 36 ans=mid; 37 } 38 else{ 39 L=mid+1; 40 } 41 } 42 printf("%d\n",ans); 43 return 0; 44 }