任务分配

题目描述

图书馆按顺序排列有N本书须要维护,每本书的总页数不相同。现有M位员工。能够给每一个员工分配连续的一段书籍,让他进行维护。如今的问题是,怎么样分配,工做任务最重(须要维护的页数最多)的人维护的页数尽可能少。ios

输入

第一行两个数,N、M。接下来N行,每行一个整数,表示一本书的页数。spa

输出

任务最重的人最少须要维护的页数。code


这道题就是求最大那我的最少要维护的数量,显而易见,二分求答案。it

left=单个a[i]最小。
right=∑a[i]。io

好了,那么check怎么写列?
l=前i个a[i]的和。
若是l>mid那么j++,l=a[i]。class

接着check就写完了,接下来stream

你渴望力量吗?变量

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
//头
int a[100000 + 10], m, n, mid;
//定义变量(`-&-感受有点尴尬`)
int check()
{
    int i, j = 1, l = 0;
    for(i = 1; i <= n; i++)
    {
        l += a[i];//加上这一本书
        if(l > mid)//若是超过了预期
            j++, l = a[i];//j++,l从新计数
    }
    if(j <= m) 
    /*若是分这么多不超过mid的段也分不了,mid就要调整,即返回0*/
    /*形象一点,若,预计每人维护<=mid页,当没分完时,减小mid,当不够分时,mid增长*/
        return 1;//不够分 mid+
    else 
        return 0;//没分完 mid-
}

int main()
{
    int i, j, left = 0, right = 0;
   scanf("%d%d", &n, &m);
    for(i = 1;i <= n; i++)
    {
        scanf("%d", &a[i]);
        right += a[i];
        if(a[i] > left) 
            left = a[i];
    }
    //read读入
    if(m == n)
    {
        printf("%d", left);
        return 0;
    }
    while(left < right)
    {
        mid = (left + right) / 2;
        if(check())
            right = mid;//mid减小
        else 
            left = mid + 1;//mid增大
    }

    printf("%d", right);//答案就在right
    return 0;
}
相关文章
相关标签/搜索