【OD】【E卷】【真题】【200分】项目排期(PythonJavaJavaScriptC++C)

题目描述

项目组共有N个开发人员,项目经理接到了M个独立的需求,每个需求的工作量不同,且每个需求只能由一个开发人员独立完成,不能多人合作。假定各个需求直接无任何先后依赖关系,请设计算法帮助项目经理进行工作安排,使整个项目能用最少的时间交付。

输入描述

第一行输入为M个需求的工作量,单位为天,用逗号隔开。

例如:X1 X2 X3 … Xm 。表示共有M个需求,每个需求的工作量分别为X1天,X2天…Xm天。

其中0<M<30;0<Xm<200

第二行输入为项目组人员数量N

输出描述

最快完成所有工作的天数

用例

输入:

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天。

解题思路

给定一系列任务的工作量和一定数量的工人,计算完成所有任务所需的最少天数,使得每个工人分配到的任务总工作量不超过这个天数。这是一个典型的搜索问题,可以通过回溯法和二分查找结合来解决。

  1. 排序和反转任务数组

    • 使用Arrays.sort(tasks)对任务数组进行升序排序,然后通过一个循环将数组反转,使其成为降序。这样做是为了优先分配工作量大的任务,从而更高效地利用工人的工作时间。
  2. 二分查找

    • 为了找到完成所有任务所需的最少天数,使用二分查找确定这个最小值。设置两个指针lr,分别表示可能的最短时间的下界和上界。l初始化为数组中的最大值(即最大的单个任务工作量),r初始化为所有任务工作量的总和。
    • l小于r的条件下进行循环,计算中间值mid,并使用canFinish函数检查是否可以在mid天内完成所有任务。
    • 如果可以完成,则将上界r设置为mid,否则将下界l设置为mid + 1
    • lr相遇时,l即为所求的最少天数。
  3. 回溯法

    • canFinish函数使用回溯法来检查在给定的时间限制limit内是否可以完成所有任务。
    • 创建一个长度为工人数量k的数组workers,用于记录每个工人的当前工作量。
    • 使用backtrack函数递归地尝试为每个任务分配工人,直到所有任务都被分配或者无法在时间限制内完成分配。
    • backtrack函数中,如果当前工人可以在时间限制内完成当前任务,则将任务分配给他,并递归地尝试分配下一个任务。
    • 如果分配成功,则返回true;如果当前路径无法成功分配所有任务,则回溯到上一个状态,尝试其他可能的分配方案。
    • 如果所有方案都无法成功,则返回false

C++

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <sstream> 
using namespace std;
// 回溯法
bool backtrack(vector<int>& tasks, vector<int>& workers, int index, int limit) {// 如果所有任务都已分配,则返回trueif (index >= tasks.size()) {return true;}// 获取当前任务的工作量int current = tasks[index];// 尝试将当前任务分配给每个员工for (int i = 0; i < workers.size(); i++) {// 如果当前员工可以在时间限制内完成这项任务if (workers[i] + current <= limit) {// 分配任务给当前员工workers[i] += current;// 继续尝试分配下一个任务if (backtrack(tasks, workers, index + 1, limit)) {return true;}// 回溯,取消当前的任务分配workers[i] -= current;}// 如果当前员工没有任务或者加上当前任务刚好达到时间限制,则不需要尝试其他员工if (workers[i] == 0 || workers[i] + current == limit) {break;}}// 如果无法分配当前任务,则返回falsereturn false;
}
// 检查是否可以在给定的时间限制内完成所有任务
bool canFinish(vector<int>& tasks, int k, int limit) {// 创建一个数组来记录每个员工的工作量vector<int> workers(k, 0);// 使用回溯法检查是否可以完成return backtrack(tasks, workers, 0, limit);
}
// 计算完成所有任务所需的最少天数
int minimumTimeRequired(vector<int>& tasks, int k) {// 将任务按工作量降序排序sort(tasks.begin(), tasks.end(), greater<int>());// 使用二分查找确定完成所有任务的最短时间int l = tasks[0], r = accumulate(tasks.begin(), tasks.end(), 0);while (l < r) {int mid = (l + r) / 2;// 检查当前时间限制是否足够完成所有任务if (canFinish(tasks, k, mid)) {r = mid;} else {l = mid + 1;}}// 返回最短完成时间return l;
}int main() {// 使用cin读取输入vector<int> tasks;string input;getline(cin, input);istringstream iss(input);int value;while (iss >> value) {tasks.push_back(value);}int N;cin >> N;// 输出最快完成所有工作的天数cout << minimumTimeRequired(tasks, N) << endl;return 0;
}

Java

import java.util.Arrays;
import java.util.Scanner;public class Main {public static void main(String[] args) {// 使用Scanner读取输入Scanner scanner = new Scanner(System.in);// 读取第一行输入,即需求的工作量,并以空格分隔String[] workloads = scanner.nextLine().split(" ");// 读取第二行输入,即项目组人员数量int N = Integer.parseInt(scanner.nextLine());// 创建一个数组来存放每个需求的工作量int[] tasks = new int[workloads.length];// 将输入的工作量转换为整数并存入数组for (int i = 0; i < workloads.length; i++) {tasks[i] = Integer.parseInt(workloads[i]);}// 输出最快完成所有工作的天数System.out.println(minimumTimeRequired(tasks, N));}// 计算完成所有任务所需的最少天数public static int minimumTimeRequired(int[] tasks, int k) {// 将任务按工作量升序排序Arrays.sort(tasks);// 将排序后的数组反转,使之成为降序int low = 0, high = tasks.length - 1;while (low < high) {int temp = tasks[low];tasks[low] = tasks[high];tasks[high] = temp;low++;high--;}// 使用二分查找确定完成所有任务的最短时间int l = tasks[0], r = Arrays.stream(tasks).sum();while (l < r) {int mid = (l + r) / 2;// 检查当前时间限制是否足够完成所有任务if (canFinish(tasks, k, mid)) {r = mid;} else {l = mid + 1;}}// 返回最短完成时间return l;}// 检查是否可以在给定的时间限制内完成所有任务private static boolean canFinish(int[] tasks, int k, int limit) {// 创建一个数组来记录每个员工的工作量int[] workers = new int[k];// 使用回溯法检查是否可以完成return backtrack(tasks, workers, 0, limit);}// 回溯法private static boolean backtrack(int[] tasks, int[] workers, int index, int limit) {// 如果所有任务都已分配,则返回trueif (index >= tasks.length) {return true;}// 获取当前任务的工作量int current = tasks[index];// 尝试将当前任务分配给每个员工for (int i = 0; i < workers.length; i++) {// 如果当前员工可以在时间限制内完成这项任务if (workers[i] + current <= limit) {// 分配任务给当前员工workers[i] += current;// 继续尝试分配下一个任务if (backtrack(tasks, workers, index + 1, limit)) {return true;}// 回溯,取消当前的任务分配workers[i] -= current;}// 如果当前员工没有任务或者加上当前任务刚好达到时间限制,则不需要尝试其他员工if (workers[i] == 0 || workers[i] + current == limit) {break;}}// 如果无法分配当前任务,则返回falsereturn false;}
}

javaScript

const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout
});// 读取输入
rl.on('line', (line) => {if (!this.tasks) {// 第一次输入,处理任务工作量this.tasks = line.split(' ').map(Number);} else {// 第二次输入,处理员工数量const N = Number(line);// 输出最快完成所有工作的天数console.log(minimumTimeRequired(this.tasks, N));rl.close();}
});// 计算完成所有任务所需的最少天数
function minimumTimeRequired(tasks, k) {// 将任务按工作量降序排序tasks.sort((a, b) => b - a);// 使用二分查找确定完成所有任务的最短时间let l = tasks[0], r = tasks.reduce((a, b) => a + b, 0);while (l < r) {let mid = Math.floor((l + r) / 2);// 检查当前时间限制是否足够完成所有任务if (canFinish(tasks, k, mid)) {r = mid;} else {l = mid + 1;}}// 返回最短完成时间return l;
}// 检查是否可以在给定的时间限制内完成所有任务
function canFinish(tasks, k, limit) {// 创建一个数组来记录每个员工的工作量let workers = new Array(k).fill(0);// 使用回溯法检查是否可以完成return backtrack(tasks, workers, 0, limit);
}// 回溯法
function backtrack(tasks, workers, index, limit) {// 如果所有任务都已分配,则返回trueif (index >= tasks.length) {return true;}// 获取当前任务的工作量let current = tasks[index];// 尝试将当前任务分配给每个员工for (let i = 0; i < workers.length; i++) {// 如果当前员工可以在时间限制内完成这项任务if (workers[i] + current <= limit) {// 分配任务给当前员工workers[i] += current;// 继续尝试分配下一个任务if (backtrack(tasks, workers, index + 1, limit)) {return true;}// 回溯,取消当前的任务分配workers[i] -= current;}// 如果当前员工没有任务或者加上当前任务刚好达到时间限制,则不需要尝试其他员工if (workers[i] === 0 || workers[i] + current === limit) {break;}}// 如果无法分配当前任务,则返回falsereturn false;
}

Python

# Python版本代码
from itertools import combinationsdef minimumTimeRequired(tasks, k):# 将任务按工作量降序排序tasks.sort(reverse=True)# 使用二分查找确定完成所有任务的最短时间l, r = tasks[0], sum(tasks)while l < r:mid = (l + r) // 2# 检查当前时间限制是否足够完成所有任务if canFinish(tasks, k, mid):r = midelse:l = mid + 1# 返回最短完成时间return ldef canFinish(tasks, k, limit):# 创建一个数组来记录每个员工的工作量workers = [0] * k# 使用回溯法检查是否可以完成return backtrack(tasks, workers, 0, limit)def backtrack(tasks, workers, index, limit):# 如果所有任务都已分配,则返回Trueif index >= len(tasks):return True# 获取当前任务的工作量current = tasks[index]# 尝试将当前任务分配给每个员工for i in range(len(workers)):# 如果当前员工可以在时间限制内完成这项任务if workers[i] + current <= limit:# 分配任务给当前员工workers[i] += current# 继续尝试分配下一个任务if backtrack(tasks, workers, index + 1, limit):return True# 回溯,取消当前的任务分配workers[i] -= current# 如果当前员工没有任务或者加上当前任务刚好达到时间限制,则不需要尝试其他员工if workers[i] == 0 or workers[i] + current == limit:break# 如果无法分配当前任务,则返回Falsereturn Falseif __name__ == "__main__":# 使用input读取输入tasks = list(map(int, input().split()))N = int(input())# 输出最快完成所有工作的天数print(minimumTimeRequired(tasks, N))

C语言

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_TASKS 30 // 定义最大任务数量的常量,用于设置任务数组的最大长度// 用于qsort函数的比较函数,实现降序排序
int compare(const void *a, const void *b) {// 将void指针转换为int指针,并解引用获取值进行比较return (*(int*)b - *(int*)a);
}// 回溯法分配任务
int backtrack(int *tasks, int *workers, int index, int limit, int k, int taskSize) {// 检查是否所有任务都已分配if (index >= taskSize) {return 1; // 如果是,返回1表示成功}// 获取当前要分配的任务int current = tasks[index];// 遍历所有员工for (int i = 0; i < k; i++) {// 检查当前员工是否可以在时间限制内完成这个任务if (workers[i] + current <= limit) {// 如果可以,分配任务并递归尝试分配下一个任务workers[i] += current;if (backtrack(tasks, workers, index + 1, limit, k, taskSize)) {return 1;}// 如果不成功,回溯,即撤销这次任务分配workers[i] -= current;}// 如果当前员工没有任务或者加上当前任务刚好达到时间限制,则不需要尝试其他员工if (workers[i] == 0 || workers[i] + current == limit) {break;}}// 如果无法分配当前任务,返回0表示失败return 0;
}// 检查是否能在指定时间内完成所有任务
int canFinish(int *tasks, int k, int limit, int taskSize) {// 初始化一个记录员工当前任务量的数组int workers[MAX_TASKS] = {0};// 调用回溯法尝试分配任务return backtrack(tasks, workers, 0, limit, k, taskSize);
}// 计算完成所有任务的最短时间
int minimumTimeRequired(int *tasks, int k, int taskSize) {// 先对任务进行降序排序qsort(tasks, taskSize, sizeof(int), compare);// 二分查找的左右边界,左边界为最大单个任务时间,右边界为所有任务时间总和int l = tasks[0], r = 0;for (int i = 0; i < taskSize; i++) {r += tasks[i];}// 二分查找最短完成时间while (l < r) {int mid = l + (r - l) / 2;// 检查是否能在mid时间内完成所有任务if (canFinish(tasks, k, mid, taskSize)) {r = mid;} else {l = mid + 1;}}// 返回最短完成时间return l;
}int main() {// 存储任务的数组和任务数量int tasks[MAX_TASKS], taskSize = 0;// 读取一行输入作为任务工作量char input[200];fgets(input, 200, stdin);// 使用strtok分割字符串,将分割后的数字转换为int存入任务数组char *token = strtok(input, " ");while (token != NULL) {tasks[taskSize++] = atoi(token);token = strtok(NULL, " ");}// 读取员工数量int N;scanf("%d", &N);// 计算并输出完成所有任务的最短时间printf("%d\n", minimumTimeRequired(tasks, N, taskSize));return 0;
}

完整用例

用例1

5 5 5 5 5 5 5 5 5 5
2

用例2

1 2 3 4 5 6 7 8 9 10
5

用例3

10 20 30 40 50 60 70 80 90 100
4

用例4

12 12 12 12 12 12 12 12 12 12 12 12
3

用例5

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
7

用例6

7 13 19 25 31 37 43 49 55 61 67 73 79 85 91 97 103 109 115 121
6

用例7

6 2 7 7 9 3 2 1 3 11 4
2

用例8

8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
5

用例9

7 13 24 31 47 56 62
3

用例10

3 6 9 12 15 18 21 24 27 30
6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/882594.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

构建高效在线考试平台:Spring Boot与JavaWeb的融合

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理基于JavaWeb技术的在线考试系统设计与实现…

颜廷利:东方智慧的现代诠释者

人文公社 2024年10月21日 东方智者颜廷利, 哲学思想论古今, 和善互爱满天下, 无私奉献情意深… 在当代哲学与文化交融的浪潮中,颜廷利以其深邃的东方智慧和对古今思想的独到见解,成为了一位备受瞩目的思想家。他不仅倡导和谐共处、互爱互助的理念,更以自身的行动践行着无私…

Hi3061M——VL53L0X激光测距(IIC)(同样适用于其他MCU)2

目录 前言资源下载移植基本使用IO配置调用测量 总结 前言 昨晚太晚了&#xff0c;草草结束了上一篇&#xff0c;今天更新下半部分。 昨天已经讲了VL53L0X的使用流程&#xff0c;无非就是进行6步的效准初始化&#xff0c;然后配置下模式和时间&#xff0c;开始采样&#xff0c;…

Yolov10训练的餐盘菜品目标检测软件(包含源码及数据集)

本文摘要 摘要&#xff1a;本文主要使用YOLOV10深度学习框架自训练了一个“餐盘菜品目标检测模型”&#xff0c;基于此模型使用PYQT5实现了一款界面软件用于功能演示。让您可以更好的了解和学习&#xff0c;该软件支持图片、视频以及摄像头进行目标检测&#xff0c;本系统所涉…

【python】OpenCV—Fun Mirrors

文章目录 1、准备工作2、原理介绍3、代码实现4、效果展示5、参考 1、准备工作 pip install vacm2、原理介绍 在OpenCV中&#xff0c;VCAM 库是一个用于简化创建三维曲面、定义虚拟摄像机、设置参数以及进行投影任务的工具。它特别适用于实现如哈哈镜等图像变形效果。 一、VC…

AI自动生成PPT哪个软件好?智能生成PPT不再熬夜做课件

大概这世上&#xff0c;都是职场牛马对“PPT”这三个字母的头痛反应最大吧&#xff01; 是的&#xff0c;就连各个年级段的老师也是很头痛——愁着怎样能在排版整齐的情况下&#xff0c;将必考知识点都呈现在PPT每一张幻灯片页面里...... 近期打听到用人工智能生成ppt课件&am…

React 项目热更新失效问题的解决方案和产生的原因

背景和意义 在修复React项目热更新失效的问题时&#xff0c;经过一系列问题排查和依赖升级&#xff0c;最终成功修复了问题并为后续开发规避了类似的问题。 依赖升级 Vite版本升级 原React项目Vite版本升级到^4.4.5 Vite 4 在构建和开发服务器的性能上进行了优化&#xff…

R01 vue+springboot 高考志愿推荐AI问答大数据平台

可以查看本文系统对应的视频讲解&#xff1a; vuespringboot 高考推荐AI问答志愿推荐大数据 R01 带增删改查、大屏、支持爬虫 1 系统背景 近年来&#xff0c;高考作为中国教育体系中最重要的考试之一&#xff0c;承载了无数考生和家庭的梦想。随着信息技术的迅猛发展&#xff…

直击工博会|可靠的数据传输与洞察,助力工业设备实现灵活互联

2024 年 9 月 24 日&#xff0c;第 25 届中国国际工业博览会在国家会展中心&#xff08;上海&#xff09;隆重开幕。今年&#xff0c;HMS 工业网络再度强势出击&#xff0c;携多款创新解决方案亮相于 6.1H-B112 展位。特别值得一提的是&#xff0c;HMS 旗下的红狮控制&#xff…

UDP/TCP协议详解

目录 一,自定义应用层协议: 1)xml 2),JSON 3),yml 4),google protobuffer 二,传输层UDP/TCP: UDP协议: TCP协议: TCP的核心机制一:确认应答 TCP核心机制二:超时重传 TCP核心机制三:连接管理 TCP核心机制四:滑动窗口 TCP核心机制五:流量控制 TCP核心机制六:拥塞控制…

HT6881 4.7W防削顶单声道音频功率放大器

1 特性 ● 防削顶失真功能(Anti-Clipping Function,ACF) ● AB类/D类切换 ● 优异的全带宽EMI抑制性能 ● 免滤波器数字调制&#xff0c;直接驱动扬声器 ● 输出功率 1.4W (VDD3.6V, RL4Ω, THDN10%, Class D) 2.8W(VDD5.0V,RL4Ω, THDN10%, ClassD) 4.7W(VDD6.5V,RL4Ω, THDN…

Maven--简略

简介 Apache旗下的一款开源项目&#xff0c;用来进行项目构建&#xff0c;帮助开发者管理项目中的jar及jar包之间的依赖&#xff0c;还拥有项目编译、测试、打包的功能。 管理方式 统一建立一个jar仓库&#xff0c;把jar上传至统一的仓库&#xff0c;使用时&#xff0c;配置…

期货外盘行情源7个市场CTP推送式服务说明

在期货交易领域&#xff0c;及时、准确的市场行情信息是投资者做出决策的重要依据。为了满足广大期货投资者对国际期货市场信息的迫切需求&#xff0c;我们特别推出了“期货外盘行情源2千每月7个市场CTP推送式”服务。本服务旨在通过高效、稳定的技术手段&#xff0c;为投资者提…

基于SpringBoot设计模式之结构型设计模式·桥接模式

文章目录 介绍开始架构图定义类的功能定义类的实现 测试样例 总结 介绍 将抽象部分与它的实现部分分离&#xff0c;使他们都可以独立地发生变化。 Bridge的意思是桥梁。就像在现实世界中&#xff0c;桥梁的功能是将河流的两侧连接起来一样, Bridge模式的作用也是将两样东西连接…

鸿蒙网络编程系列3-TCP客户端通讯示例

1. TCP简介 TCP协议是传输层最重要的协议&#xff0c;提供了可靠、有序的数据传输&#xff0c;是多个广泛使用的表示层协议的运行基础&#xff0c;相对于UDP来说&#xff0c;TCP需要经过三次握手后才能建立连接&#xff0c;建立连接后才能进行数据传输&#xff0c;所以效率差了…

Go_Parser部署、使用与原理分析

文章目录 前言1、概述2、安装与使用2.1、源码安装2.1.1、部署系统依赖组件2.1.1.1、部署IDA Pro 7.5 SP32.1.1.2、部署Python 3.9.132.1.1.3、部署Go 1.13.1 2.1.2、使用源码安装系统 2.2、使用方法2.2.1、准备测试程序2.2.2、创建IDA Pro项目2.2.3、使用Go_Parser解析二进制程…

植物大战僵尸杂交版游戏分享

植物大战僵尸杂交版游戏下载&#xff1a;夸克网盘分享 无捆绑之类的隐形消费&#xff0c;下载即玩

电力调度控制中心在电力系统中的作用

在庞大而复杂的电力系统中&#xff0c;电力调度控制中心犹如一颗智慧的心脏&#xff0c;扮演着不可或缺的角色。它不仅是电力输送与分配的指挥官&#xff0c;更是确保电网安全、稳定、高效运行的守护者。关于电力调度控制中心在电力系统中的作用&#xff0c;我们具体了解一下。…

全新子比主题7.9.2开心版 子比主题最新版源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 wordpress zibll子比主题7.9.2开心版 修复评论弹授权 可做付费下载站 含wordpress搭建视频教程zibll子比主题安装视频教程支付配置视频教程&#xff0c;视频都是语音讲解&#xff0c;…

AI产品经理:从入门到精通,一篇文章带你入门!(附学习资料)

一、AI产品经理工作全流程概览 AI产品经理工作全流程中与普通产品经理的区别主要是多了算法模型部分&#xff0c;包括模型预研、数据准备、模型构建、模型宣讲、模型验收&#xff0c;协作的对象相对普通产品经理也多了算法工程师。 二、需求定义 需求定义主要要定义清楚以下几…