P1182 数列分段 Section II

题意:给出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 }
View Code

 

posted @ 2020-04-10 22:22  古比  阅读(148)  评论(0编辑  收藏  举报