【华为OD机试真题】423、项目排期 、最快完成所有工作的天数 | 机试真题+思路参考+代码解析(CD卷)(C++)

一、题目

题目描述

项目组共有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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值