题意
给出农夫在n天中每天的花费,要求把这n天分作m组,每组的天数必然是连续的,要求分得各组的花费之和应该尽可能地小,最后输出各组花费之和中的最大值
思路:
1 普通枚举(超时)
先把N个值中的最大值Max作为作为分组的最小和,然后暴力分组看看分的组数是不是小于m
如果小于m就找到了
如果不小于 就让Max++;一直枚举到满足条件的值为止
2 二分 枚举不是Max++进行了 ,而是先确定一个最大和与最小和
然后二分判断边界
二分的条件知道上下边界即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
int a[100010];
int n,m;
int judge(int low,int high)
{
if(low>=high)
return low;
int sum,num,mid;
int zmax=high;
while(low<=high) ///勿漏 =
{
mid=(low+high)/2;
sum=0;
num=1;
for(int i=0; i<n; i++)
{
if(sum+a[i]<=mid)
sum+=a[i];
else
{
sum=a[i];
num++;
}
if(num>m)
break;
}
if(num>m)
low=mid+1;
else ///满足分组条件
{
high=mid-1;
zmax=min(zmax,mid); ///确定满足分组条件的最小值
}
}
return zmax;
}
int main()
{
// freopen("stdd.txt","r+",stdin);
// freopen("std.txt","w+",stdout);
while(~scanf("%d%d",&n,&m))
{
int low=-1,high=0;
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
high+=a[i];
low=max(a[i],low);
}
printf("%d\n",judge(low,high));
}
return 0;
}