点击打开链接
题意
给出农夫在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; }