[YBT High-Efficiency Advanced] 1 Basic Algorithm/3 Dichotomous Algorithm/1 Sequence Segmentation & [Luogu] P1182 Sequence Segmentation

[YBT High-Efficiency Advanced] 1 Basic Algorithm/3 Dichotomous Algorithm/1 Sequence Segmentation & [Luogu] P1182 Sequence Segmentation

Title description

For a given sequence of positive integers A 1 to A N of length N , it is now divided into M ( M ≤ NM\leq NMN ) segments, and each segment is required to be continuous, and the maximum sum of each segment is the smallest.

About the maximum and minimum:

For example, a number 4 2 4 5 1 should be divided into 33 segments.

Divide it as follows:
[4 2][4 5][1]

The sum of the first segment is 6, the sum of the second segment is 9, and the sum of the third segment is 1, and the maximum sum is 9.

Segment it as follows:

[4][2 4][5 1]

The sum of the first segment is 4, the sum of the second segment is 6, and the sum of the third segment is 6, and the maximum sum is 6.

And in any case, the maximum value will not be less than 6.

So we can get the number sequence 4 2 4 5 1 to be divided into 3 segments, and the minimum sum of each segment is 6.

Input format

Line 1 contains two positive integers N and M.

Line 2 contains non-negative integers A i separated by N spaces . The meaning is as described in the title.

Output format

A positive integer, which is the minimum value of each segment and maximum value.

Sample input and output

Enter #1 to copy
5 3
4 2 4 5 1
Output #1 copy
6

Instructions/tips

For 20% of the data, N ≤ 10 N \leq 10N10

For 40% of the data, N ≤ 1000 N\leq 1000N1000

For 100% data, 1 ≤ N ≤ 1 0 5, M ≤ N, 1\leq N\leq 10^5, M\leq N,1N105MN , Ai<108, the answer is no more than 109.

Ideas

The maximum value of binary enumeration is checked once.

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long a[100010],n,m;
bool check(long long x)//检查是否符合条件 
{
    
    
	long long sum=0,cnt=1,i;
	for(i=1;i<=n;i++)
	{
    
    
		if(sum+a[i]<=x)
			sum+=a[i];
		else
		{
    
    
			cnt++;
			sum=a[i];
		}
	}
	return (cnt<=m);
}
int main()
{
    
    
	long long i,ans,l,r,mid;
	scanf("%lld%lld",&n,&m);
	for(i=1,l=r=0;i<=n;i++)
		scanf("%lld",&a[i]),l=max(l,a[i]),r+=a[i];
	while(l<r)//二分查找 
	{
    
    
		mid=(l+r)>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	printf("%lld",l);
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_46975572/article/details/113058004