码迷,mamicode.com
首页 > 其他好文 > 详细

数列分段II(二分)

时间:2019-07-27 16:59:11      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:syn   algorithm   font   medium   event   code   最大   连续   stream   

对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小。

关于最大值最小:

例如一数列4 2 4 5 1要分成3段

将其如下分段:

[4 2][4 5][1]

第一段和为6,第2段和为9,第3段和为1,和最大值为9。

将其如下分段:

[4][2 4][5 1]

第一段和为4,第2段和为6,第3段和为6,和最大值为6。

并且无论如何分段,最大值不会小于6。

所以可以得到要将数列4 2 4 5 1要分成3段,每段和的最大值最小为6。

 

 

 

输入

 

 

第1行包含两个正整数N,M,第2行包含N个空格隔开的非负整数A[i],含义如题目所述。

M<=N<=100000, A[i]之和不超过109

 

 

输出

 

 

仅包含一个正整数,即每段和最大值最小为多少。

 

 

样例输入

 

样例输出

 

解题思路:最大值的最小 二分 

技术图片
 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int sum;
 6 int maxx;
 7 int n,m;
 8 int arr[100005];
 9 
10 int check(int num){
11     int ans=0,res=0;
12     for(int i=1;i<=n;i++){
13         if(ans+arr[i]<=num) ans+=arr[i];
14         else ans=arr[i],res++;
15     }
16     if(res>=m) return 0;
17     else return 1;
18 }
19 
20 int Calculation(int left,int right){
21     while(left<=right){
22         int mid=left+right>>1;
23         if(check(mid)==1) right=mid-1;
24         else left=mid+1;
25     }
26     return left;
27 }
28 
29 int main(){
30     ios::sync_with_stdio(false);
31     cin>>n>>m;
32     for(int i=1;i<=n;i++){
33         cin>>arr[i];
34         sum+=arr[i];
35         maxx=max(maxx,arr[i]);
36     }
37     cout << Calculation(maxx,sum) << endl;
38     return 0;
39 }
View Code

 

数列分段II(二分)

标签:syn   algorithm   font   medium   event   code   最大   连续   stream   

原文地址:https://www.cnblogs.com/qq-1585047819/p/11255723.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!