POJ 3273 Monthly Expense(二分)
题目链接
题目大意:找出一个最小值\(x\),使\(n\)个数能分成\(m\)个和小于\(x\)的连续区间。
很显然的二分判定答案,不过需要注意有坑,二分的答案必须大于等于\(n\)个数中的每一个数。比如5 5 100 200 300 400 500这个数据,答案是\(500\),很明显小于\(500\)的话根本无法全部吃完。
const int maxn = 1e5+10;
int n, m, arr[maxn];
bool checker(int num) {
int cnt = 0, sum = 0;
for (int i = 0; i<n; ++i) {
if (arr[i]>num) return true;
//如果当前的解比其中一个数大的话肯定不行,需要增大下界
if (sum+arr[i]<=num) sum += arr[i];
else {
++cnt;
sum = arr[i];
}
}
if (sum) ++cnt;
return cnt>=m;
}
int main(void) {
while(~scanf("%d%d", &n, &m)) {
for (int i = 0; i<n; ++i) scanf("%d", &arr[i]);
int l = 0, r = INF;
while(l<=r) {
int mid = (l+r)>>1;
if (checker(mid)) l = mid+1;
else r = mid-1;
}
printf("%d\n", r);
}
return 0;
}