题目
部门在进行需求开发时需要进行人力安排。
当前部门需要完成 N 个需求,需求用 requirements 表述,requirements[i] 表示第 i 个需求的工作量大小,单位:人月。
这部分需求需要在 M 个月内完成开发,进行人力安排后每个月人力时固定的。
目前要求每个月最多有2个需求开发,并且每个月需要完成的需求不能超过部门人力。
请帮助部门评估在满足需求开发进度的情况下,每个月需要的最小人力是多少?
题目输入
输入为 M 和 requirements,M 表示需求开发时间要求,requirements 表示每个需求工作量大小,N 为 requirements长度,
- 1 ≤ N/2 ≤ M ≤ N ≤ 10000
- 1 ≤ requirements[i] ≤ 10^9
题目输出
对于每一组测试数据,输出部门需要人力需求,行末无多余的空格
实例
输入 | 3 3 5 3 4 |
输出 | 6 |
说明 | 输入数据两行, 第一行输入数据3表示开发时间要求, 第二行输入数据表示需求工作量大小, 输出数据一行,表示部门人力需求。 当选择人力为6时,2个需求量为3的工作可以在1个月里完成,其他2个工作各需要1个月完成。可以在3个月内完成所有需求。 当选择人力为5时,4个工作各需要1个月完成,一共需要4个月才能完成所有需求。 因此6是部门最小的人力需求。 |
题目解析
题目
题目代码
#include <iostream>
#include <vector>
using namespace std;
//双指针,一个指向最小,一个指向最大。假设每个月需要的最小人力是mid
bool check(vector<int>& nums, int mid, int M){
int cnt = 0;//当前所花费的时间
int left = 0;
int right = nums.size() - 1;
while(left <= right){
if(nums[left] + nums[right] <= mid){
left++;
right--;
}else{//nums[left] + nums[right] > mid,说明nums[right]单独一个月完成,指向左移。
right--;
}
cnt++;
}
if(cnt <= M) return true;
return false;
}
int main(){
int M;
cin >> M;//输入开发时间
int val;
vector<int> nums;
while(cin >> val){//输入每个需求工作量大小
nums.push_back(val);
if(cin.peek() == '\n') break;
}
if(nums.size() == 1) {
cout << nums[0] << endl;
return 0;
}
sort(nums.begin(), nums.end());
//满足单调性,所以使用二分法
int left = nums.back();//每个月需要完成的需求开发,不能超过部门人力。这保证,单个需求在对于部门人力肯定能开发完。
int right = nums.back() + nums[nums.size() - 2];//目前要求每个月最多有2个需求开发,所以最大就是最大两个的和。
while(left <= right){
cout<<"le = "<<left<<endl;
cout<<"ri = "<<right<<endl;
int mid = left + (right - left)/2;//防止溢出
if(check(nums, mid, M)){
right = mid - 1;
}else{
left = mid + 1;
}
}
cout << left << endl;
return 0;
}