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;
}
posted @ 2020-04-21 09:37  shuitiangong  阅读(81)  评论(0编辑  收藏  举报