一、题目
题目描述
项目组共有N个开发人员,项目经理接到了M个独立的需求,每个需求的工作量不同,且每个需求只能由一个开发人员独立完成,
不能多人合作。假定各个需求直接无任何先后依赖关系,请设计算法Q帮助项目经理进行工作安排,使整个项目能用最少的时间交
付
输入输出
输入
第一行输入为M个需求的工作量,单位为天,用逗号隔开。
例如:X1,X2,X3…Xm
表示共有M个需求,每个需求的工作量分别为X1天,X2天…Xm天。其中0<M<30; 0<Xm<200
第二行输入为项目组人员数量N,例如:表示共有5名员工,其中0<N<10
输出
最快完成所有工作的天数
样例1
输入
6 2 7 7 9 3 2 1 3 11 4
2
输出
28
说明:
共有两位员工,其中一位分配需求6 2 7 7 3 2 1共需要28天完成,另一位分配需求9 3 11 4共需要27天完成,故完成所有工作至少需要28天。
样例2
输入
3 6 9 12 15 18 21 24 27 30
6
输出
30
一、代码与思路
🧠C++语言思路
1.首先,将需求的工作量按照从大到小排序,以平衡员工的负载。
2.创建一个长度为N的数组employee hours,用于记录每个员工已分配的工作量。
3.初始化一个变量min time为INT MAX,用于记录最短完成时间。
4.使用回溯法尝试所有的分配方案:
。定义一个回溯函数backtrack,参数为当前需求的索引i。
如果所有任务已分配完毕,更新最短完成时间为employee hours数组中的最大值,然后返回。
0
遍历所有员工,尝试将当前需求分配给每个员工:
0
·如果当前分配方案已经超过最短时间,跳过。
·将当前需求的工作量加到该员工的工作量中。
。递归调用backtrack函数,继续分配下一个需求。
·将当前需求的工作量从该员工的工作量中减去(回溯)
5.调用回溯函数backtrack(0)开始尝试所有分配方案。
6.返回最短完成时间min time作为结果。
✅C++代码
//此解法在面对大数据的时候,算法复杂度较高,大家记得优化一下
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <climits>
using namespace std;
// 分配任务的函数
int distributeTasks(vector<int>& workloads, int N) {
// 从大到小排序工作量,以平衡员工负载
sort(workloads.rbegin(), workloads.rend());
vector<int> employee_hours(N, 0);
int min_time = INT_MAX;
// 使用回溯法尝试所有分配方案
function<void(int)> backtrack = [&](int i) {
// 如果所有任务已分配,更新最短完成时间
if (i == workloads.size()) {
min_time = min(min_time, *max_element(employee_hours.begin(), employee_hours.end()));
return;
}
for (int j = 0; j < N; ++j) {
// 如果当前分配方案已经超过最短时间,跳过
if (employee_hours[j] + workloads[i] > min_time) continue;
employee_hours[j] += workloads[i];
backtrack(i + 1);
employee_hours[j] -= workloads[i]; // 回溯
}
};
backtrack(0);
return min_time;
}
int main() {
string line;
getline(cin, line);
vector<int> workloads;
int x, N;
// 读取任务工作量
stringstream ss(line);
while (ss >> x) {
workloads.push_back(x);
if (ss.peek() == ',') ss.ignore();
}
// 读取员工数量
cin >> N;
cout << distributeTasks(workloads, N) << endl;
return 0;
}