题目描述
小明每周上班都会拿到自己的工作清单,工作清单内包含 n 项工作,每项工作都有对应的耗时时间(单位 h)和报酬,工作的总报酬为所有已完成工作的报酬之和,那么请你帮小明安排一下工作,保证小明在指定的工作时间内工作收入最大化。
输入描述
T 代表工作时长(单位 h, 0 < T < 1000000),
n 代表工作数量( 1 < n ≤ 3000)。
接下来是 n 行,每行包含两个整数 t,w。
t 代表该工作消耗的时长(单位 h, t > 0),w 代表该项工作的报酬。
输出描述
输出小明指定工作时长内工作可获得的最大报酬。
示例1
输入
40 3
20 10
20 20
20 5
输出
30
解题思路
本题是典型的01背包问题,其中:
- 工作时长 ( T ) 相当于背包的承重。
- 每一项工作相当于每件物品。
- 工作消耗的时长相当于物品的重量。
- 工作的报酬相当于物品的价值。
思路
-
初始化与输入:
- 首先读入工作时间 ( T ) 和工作数量。
- 读入每项工作的耗时和报酬,存储在二维数组中。
-
动态规划:
- 确定所有工作中耗时最短的那个 ( \text{min_time} ),以便从该时间开始计算dp数组。
- 初始化一个二维dp数组 ( \text{dp}[i][j] ),其中 ( \text{dp}[i][j] ) 表示前 ( i ) 项工作在 ( j ) 时间内能获得的最大报酬。
-
动态规划执行:
- 使用两个嵌套的for循环遍历工作项 ( i ) 和时间 ( j )。
- 对于第 ( i ) 项工作:
- 如果耗时 ( \text{tasks}[i-1][0] ) 大于 ( j ),则无法完成该项工作,此时最大报酬为 0。
- 否则,能完成该项工作,最大报酬为 ( \text{tasks}[i-1][1] ) 加上前 ( i-1 ) 项工作在 ( j-\text{tasks}[i-1][0] ) 时间内能获得的最大报酬。
- 更新dp数组,( \text{dp}[i][j] = \max(\text{dp}[i-1][j], \text{current}) ),其中 (\text{current}) 是如果包含当前工作所得到的报酬。
-
输出结果:
- 输出 ( \text{dp}[n][T] ),表示前 ( n ) 项工作在 ( T ) 时间内能获得的最大报酬。
Java