题目描述
小明每周上班都会拿到自己的工作清单,工作清单内包含 n 项工作,每项工作都有对应的耗时时间(单位 h)和报酬,工作的总报酬为所有已完成工作的报酬之和,那么请你帮小明安排一下工作,保证小明在指定的工作时间内工作收入最大化。
输入描述
输入的第一行为两个正整数 T,n。 T 代表工作时长(单位 h, 0 < T < 1000000), n 代表工作数量( 1 < n ≤ 3000)。 接下来是 n 行,每行包含两个整数 t,w。 t 代表该工作消耗的时长(单位 h, t > 0),w 代表该项工作的报酬。
输出描述
输出小明指定工作时长内工作可获得的最大报酬。
用例
| 输入 | 40 3 20 10 20 20 20 5 |
|---|---|
| 输出 | 30 |
| 说明 | 无 |
解题思路
问题描述
我们有一段总时长为 total_time 的时间,以及若干任务,每个任务都有以下属性:
duration:完成任务所需的时间。wage:完成任务获得的报酬。
目标是从这些任务中选择若干个,使得:
- 总时间不超过
total_time。 - 收益(任务报酬的总和)最大化。
这是一个典型的 0-1 背包问题,将任务的时间视为物品的体积,任务的报酬视为物品的价值,总时间视为背包容量。
python源码:
class JobScheduler:
def __init__(self, total_time, tasks):
self.total_time = total_time # 总时间
self.tasks = tasks # 任务列表,每个任务为 (时长, 报酬)
def calculate_max_earnings(self):
# 初始化 dp 数组
dp = [0] * (self.total_time + 1)
# 遍历每个任务
for duration, wage in self.tasks:
# 逆序更新 dp 数组,避免任务重复选择
for time in range(self.total_time, duration - 1, -1):
# 更新 dp[time],取不选择和选择当前任务的收益最大值
dp[time] = max(dp[time], dp[time - duration] + wage)
# 返回最大时间下的收益
return dp[self.total_time]
if __name__ == "__main__":
# 读取总时间和任务数量
t, n = map(int, input().split())
# 读取任务数据
tasks = [tuple(map(int, input().split())) for _ in range(n)]
# 创建任务调度器并计算结果
scheduler = JobScheduler(t, tasks)
print(scheduler.calculate_max_earnings())
java源码:
import java.util.Scanner;
class Main {
private int totalTime; // 总时间限制
private int[][] tasks; // 任务数组,每个任务包含两个值:[时长, 报酬]
// 构造函数,初始化总时间和任务数组
public Main(int totalTime, int[][] tasks) {
this.totalTime = totalTime;
this.tasks = tasks;
}
// 动态规划计算最大收益
public int calculateMaxEarnings() {
int[] dp = new int[totalTime + 1]; // dp数组,dp[time]表示总时间为time时的最大收益
// 遍历每个任务
for (int[] task : tasks) {
int duration = task[0]; // 任务时长
int wage = task[1]; // 任务报酬
// 从后向前遍历时间,避免任务重复选择
for (int time = totalTime; time >= duration; time--) {
// 选择或不选择当前任务,取最大收益
dp[time] = Math.max(dp[time], dp[time - duration] + wage);
}
}
// 返回最大时间下的最大收益
return dp[totalTime];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取总时间和任务数量
int totalTime = sc.nextInt();
int numTasks = sc.nextInt();
int[][] tasks = new int[numTasks][2]; // 任务数组
// 读取每个任务的时长和报酬
for (int i = 0; i < numTasks; i++) {
tasks[i][0] = sc.nextInt(); // 时长
tasks[i][1] = sc.nextInt(); // 报酬
}
// 创建任务调度器并计算结果
Main scheduler = new Main(totalTime, tasks);
System.out.println(scheduler.calculateMaxEarnings());
}
}
js源码:
待更新......
&spm=1001.2101.3001.5002&articleId=144092396&d=1&t=3&u=4173c51142084340a7bcd2589cb713fd)
1980

被折叠的 条评论
为什么被折叠?



