工作安排 - 华为OD统一考试(E卷)

2024华为OD机试(C卷+D卷)最新题库【超值优惠】Java/Python/C++合集

题目描述

小明每周上班都会拿到自己的工作清单,工作清单内包含n项工作,每项工作都有对应的耗时时长(单位h)和报酬,工作的总报酬为所有已完成工作的报酬之和。那么请你帮小明安排一下工作,保证小明在指定的工作时间内工作收入最大化。

输入描述

输入的第一行为两个正整数工 T,n。T 代表工作时长(单位h,0<T<100000),n代表工作数量(1<n≤3000)。

接下来是n行,每行包含两个整数t,w。t代表该项工作消耗的时长(单位h,t>0),w代表该项工作的报酬。

输出描述

输出小明指定工作时长内工作可获得的最大报酬。

示例1

复制代码
输入:
40 3
20 10
20 20
20 5

输出:
30

题解

分析

这道题属于动态规划 问题,类似于经典的0/1背包问题,即在限定的资源(工作时长)下,如何选择工作使得报酬最大化。每项工作都有消耗的时间和对应的报酬,要求在有限的总工作时间内,选择一些工作使得获得的总报酬最大。

思路

可以将每项工作看作背包中的物品,每项工作消耗的时间就是物品的重量,工作的报酬就是物品的价值。我们要在给定的工作时长限制内,选出能够使得报酬最大的工作组合。

具体来说,动态规划的思路如下:

  1. 状态定义

    • dp[i] 表示在工作时长为 i 时,能够获得的最大报酬。
  2. 状态转移

    • 对于每个工作 (t, w),表示该工作消耗时间 t并获得报酬 w。我们需要决定是否选择该工作:

      • 如果不选择,则 dp[cap] 保持不变。
      • 如果选择,则 dp[cap] = max(dp[cap], dp[cap - t] + w)
    • 从后往前遍历 dp 数组,确保每个工作只能被选择一次(类似 0/1 背包问题)。

  3. 初始化

    • dp[0] = 0 表示工作时长为 0 时的最大报酬为 0,其他 dp 初始化为 0,因为我们假设初始时还未完成任何工作。
  4. 结果

    • 最终结果就是 dp 数组中的最大值,表示在给定的总工作时长 T 内能获得的最大报酬。

Java

java 复制代码
import java.util.Scanner;
/**
 * @author code5bug
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 读取T和n的值
        int T = sc.nextInt();
        int n = sc.nextInt();

        // 初始化dp数组
        int[] dp = new int[T + 1];

        // 循环读取工作消耗的时长t和工作的报酬
        for (int i = 0; i < n; i++) {
            int t = sc.nextInt();
            int w = sc.nextInt();

            // 动态规划,从后往前遍历以避免重复使用
            for (int cap = T; cap >= t; cap--) {
                dp[cap] = Math.max(dp[cap], dp[cap - t] + w);
            }
        }

        // 找到dp数组中的最大值,即为答案
        int result = 0;
        for (int x : dp) {
            result = Math.max(result, x);
        }

        // 输出结果
        System.out.println(result);
    }
}

Python

python 复制代码
# T 工作时长,  n 工作数量
T, n = map(int, input().split())

# 初始化dp数组
dp = [0] * (T + 1)

# 循环读取工作消耗的时长t和工作的报酬
for _ in range(n):
    t, w = map(int, input().split())

    # 动态规划,从后往前遍历以避免重复使用
    for cap in range(T, t - 1, -1):
        dp[cap] = max(dp[cap], dp[cap - t] + w)

# 输出结果
print(max(dp))

C++

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    int T, n;
    cin >> T >> n;

    vector<int> dp(T + 1, 0);

    int t, w;
    for (int i = 0; i < n; i++) { // 循环读取工作消耗的时长t和工作的报酬
        cin >> t >> w;
        for (int cap = T; cap >= t; cap--) { // 动态规划,从后往前遍历以避免重复使用
            dp[cap] = max(dp[cap], dp[cap - t] + w);
        }
    }

    int result = 0;
    for (int x: dp) result = max(result, x);

    cout << result << endl;

    return 0;
}
    

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

相关推荐
崎岖Qiu4 分钟前
【设计模式笔记06】:单一职责原则
java·笔记·设计模式·单一职责原则
Hello.Reader9 分钟前
Flink ExecutionConfig 实战并行度、序列化、对象重用与全局参数
java·大数据·flink
前端炒粉1 小时前
18.矩阵置零(原地算法)
javascript·线性代数·算法·矩阵
熊小猿1 小时前
在 Spring Boot 项目中使用分页插件的两种常见方式
java·spring boot·后端
paopaokaka_luck1 小时前
基于SpringBoot+Vue的助农扶贫平台(AI问答、WebSocket实时聊天、快递物流API、协同过滤算法、Echarts图形化分析、分享链接到微博)
java·vue.js·spring boot·后端·websocket·spring
老华带你飞1 小时前
机器人信息|基于Springboot的机器人门户展示系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·机器人·论文·毕设·机器人门户展示系统
杨筱毅1 小时前
【C++】【常见面试题】最简版带大小和超时限制的LRU缓存实现
c++·面试
notion20251 小时前
Adobe Lightroom Classic下载与安装教程(附安装包) 2025最新版详细图文安装教程
java·数据库·其他·adobe
做运维的阿瑞2 小时前
用 Python 构建稳健的数据分析流水线
开发语言·python·数据分析