[Problem Solution] Sequence Subsection II

Title source: loj

Title description

For a given sequence of positive integers A−i of length N, we must now divide it into M(M≤N)M(M≤N)M(M≤N) segments, and require each segment to be continuous, and each segment The maximum value of the sum is the smallest.

About the maximum and minimum:

For example, a series of 42451 should be divided into 333 segments

Segment it as follows:

[42][45][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][24][51]

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.

Therefore, it can be obtained that the number sequence 42451 must be divided into 3 segments, and the maximum sum of each segment is at least 6.

Input format

The first line contains two positive integers N and M.

The second line contains non-negative integer Ai​ 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.

Input sample

5 3
4 2 4 5 1

Sample output

6

Description

For 20% of the data, N≤10;

For 40% of the data, N≤1000;

For 100% data, N≤100000, M≤N, and the sum of Ai​ does not exceed 10^9.

Ideas

Two-point answer
Every time you judge whether the current mid can be divided into segments greater than or equal to m , and the sum of each segment is less than or equal to mid , if possible, it means that the current mid can be greater

code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,a[N],l,r,anss;
bool check(int maxx)
{
    
    
	int now=0,cnt=0;
	for (int i=1;i<=n;i++)
	{
    
    
		if (now+a[i]<=maxx) now+=a[i];
		else cnt++,now=a[i];
		if (cnt>=m) return true;
	}
	return false;
}
int main()
{
    
    
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]),l=max(l,a[i]),r+=a[i];
	while (l<=r)
	{
    
    
		int mid=(l+r)>>1;
		if (check(mid)==true) l=mid+1; //如果当前的mid可以成功分段,则说明还可以继续减小答案 
		else r=mid-1; 
	}
	cout<<l<<endl;
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45485187/article/details/103065467
Recommended