想到用二分来尝试结果,用贪心来验证
有N个数,要分成M段,求最大值最小。显然最大值最小的情况是单个数字中最大的,最大值最大的情况是所有数组的和为最大值。
求出最大值的最小和最大可能,对此二分来尝试是否可行。
尝试可行的办法
尝试一系列数分成最大值的最小为X时至少要分几段。那就用贪心的方法,每段都在不大于最大值的情况下尽可能的大。
如此一来,能在分段在小于M个的情况下的最大值的最小值为X,那在分M段的情况下最大值的最小值肯定不比X大。
反之,如果要使分段在大于M个的情况下的最大值的最小为X,那在分M段的情况下最大值的最小肯定要部比X小。
代码如下:
#include<iostream>
using namespace std;
const int M = 100000;
int n,m;
int val[M];
int l;//分段最小的结果——最大的单个数字
int r;//分段最大的结果—— 总和
bool judge(int mid) //如果能在m段内使最大值最小为mid,返回true。如果是true,就尝试更小的
{
int count = 0;//分段数量
int loc = 0;
int sum = 0;
while(loc < n)
{
while(loc < n && sum + val[loc] <= mid) sum += val[loc++];
sum = 0;
count ++;
}
return count <= m;
}
int main()
{
cin >> n >> m; //n个数分成m段
for(int i = 0; i < n; i ++)
{
cin >> val[i];
if(val[i] > l) l = val[i];
r += val[i];
}
int mid;
while(r - l > 1)
{
mid = (r + l) / 2;
if(judge(mid)) r = mid;
else l = mid;
}
cout << r;
return 0;
}