【ybtoj】数列分段
作者:互联网
数列分段
题目描述
对于给定的一个长度为N的正整数数列A,现在将其分成M段,并要求每段连续,且每段和的最大值最小。
输入格式
第1行包含两个正整数N,M。
第2行包含N个空格隔开的非负整数
A
i
A_i
Ai。
输出格式
仅包含一个正整数,即每段和最大值最小为多少。
输入样例
5 3
4 2 4 5 1
输出样例
6
解题思路
题目描述中有类似“最大值最小”的含义,我们马上就知道这答案具有单调性。设最优解为S,因为S的最优性,如果要求每段和都<S,则肯定不能分成连续的M段,需要分成更多连续段。如果每段和可以>S,那么一定存在一种划分方案使得总段数不超过M。因此答案就处于分段可行性的分界点上。
Code
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,l,r,a[100005];
bool check(int x)
{
int sum=0,num=1;
for(int i=1;i<=n;i++)
if(sum+a[i]>x)
{
num++;
sum=a[i];
if(a[i]>x)return 0;//记得要特判
}
else sum+=a[i];
return num>m;
}
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)/2;
if(check(mid))l=mid+1;
else r=mid;
}
printf("%d",l);
return 0;
}
谢谢阅读
标签:return,数列,int,ybtoj,sum,mid,num,每段,分段 来源: https://blog.csdn.net/SSL_lyw/article/details/117837976