图书馆按顺序排列有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; }