数列分段II(二分)

Posted qq-1585047819

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数列分段II(二分)相关的知识,希望对你有一定的参考价值。

对于给定的一个长度为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(二分)的主要内容,如果未能解决你的问题,请参考以下文章

模板P1182数列分段II——二分答案

洛谷P1182 数列分段Section II 二分答案

1436:数列分段II

P1182 数列分段`Section II`

P1182 数列分段 Section II

P1182 数列分段`Section II`