题意:按顺序给你N个数,将这N个数分成连续的M段,使得这M段每段的和中的最大值最小,输出最小值(1<=N<=100000,1<=M<=N,每个数在1到10000之间)。

思路:由于函数具有单调性的特征,因此可以用二分枚举的办法去实现它,这与POJ3258有非常相似的地方,但这里不需要排序。

 

CODE:

 

 

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

const int SIZE = 100010;

int a[SIZE];
int low_bound, high_bound;
int n, m;


int BSearch(int x, int y, int m)
{
    int mid;
    while(x <= y)
    {
        int group = 1, sum = 0;
        mid = (x+y)>>1;
        for(int i = 1; i <= n; i++)
        {
            if((sum+=a[i]) <= mid);
            else
            {
                group++;
                sum = a[i];
            }
        }
        if(group > m) x = mid+1;
        else y = mid-1;
    }
    return x;
}



int main()
{
    while(~scanf("%d%d", &n, &m))
    {
        low_bound = -1;
        high_bound = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            low_bound = max(low_bound, a[i]);
            high_bound += a[i];
        }
        int ans = BSearch(low_bound, high_bound, m);
        printf("%d\n", ans);
    }
    return 0;
}

 

posted on 2012-09-04 17:14  有间博客  阅读(162)  评论(0编辑  收藏  举报