洛谷 P1182 数列分段 二分查找

在这里插入图片描述
在这里插入图片描述

Solution:

这道题让我们将数列分组,分成m组,并且求出每组的和,使每组和中的最大值最小,遇到这种我们,就要想到用二分的思想。关键就是我们怎样确定二分的范围,我们最多把数列分为n组,每组只有一个元素,找出所有元素的最大值max;最少把数列分为1组,也就是不分组,这组的和就是n个元素的和sum。而我们要求的就在max~sum之间。
代码如下:

#include<iostream>
#include<math.h>
#define MAX 100005
using namespace std;

int n,m;
int a[MAX];

bool judge(int mid){
  int cnt=0;//已经分的组数
  int sum=0;//每一组的总和值
  for(int i=0;i<n;i++){
    if(sum+a[i]<=mid){//若每组的值仍然小于等于试探的值,则继续向组里添加元素
        sum+=a[i];
    }else{//否则,就新增加一个组
        sum=a[i];
        cnt++;
    }
  }
  if(cnt>=m){//如果已经超过了最大组数限制,就返回false
    return false;
  }else{//否则,返回true
    return true;
  }
}

int main(){
  cin>>n>>m;
  int left=-1,right=0,mid;
  for(int i=0;i<n;i++){
    cin>>a[i];
    left=max(a[i],left);//left为数组中的最大值
    right+=a[i];//right为所有元素的和
  }
  while(left<=right){//二分查找
    mid=(left+right)/2;
    if(judge(mid)==true){//若mid的值在满足分组的情况下偏大
        right=mid-1;
    }else{//若mid的值偏小,不能满足分组
        left=mid+1;
    }
  }
  cout<<left;//left即为最后的值
  return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44123362/article/details/89302664