/*这个二分枚举注意的是不要超时, 以往的二分方法这里需要注意优化一下函数中将有注释*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100010;
int a[maxn];
int n, m;
int solve(int mid)
{
int sum = 0;
int cnt = 1;
for(int i = 0; i < n; i++){
if(sum + a[i] <= mid){
sum += a[i];
}
else{
sum = a[i];
cnt++;
}
}
if(cnt > m) return 0;
else
return 1;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF){
int left = -0x3f3f3f3f, right = 0, mid = 0;
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
left = max(left, a[i]);
right += a[i];
}
while(left <= right){
mid = (left+right)>>1;
if(solve(mid)) right = mid - 1;//这里注意每次从mid向上或者向下枚举不要从最大或者最小枚举
else
left = mid + 1;//这里也是
}
cout << mid << endl;
}
return 0;
}
poj3273(二分枚举)
最新推荐文章于 2019-04-20 09:48:00 发布