通过率 58% · 提交 405 · 通过 233
小慕准备从 A 城前往 B 城参加一场演出。 1. 按照合同,他必须在 T 天内到达。 2. 小慕的行程会经过 N 座城市。 3. 小慕不能走回头路。 4. 每两座城市之间需要的天数,小慕已经提前了解清楚。 5. 小慕在每座城市都可以在路边卖唱赚钱。经过调研,他提前知道了每座城市卖唱的。如果在一座城市第一天卖唱可以赚 M,之后每天的收入会减少 D(第二天赚 M-D,第三天赚 M-2D……)。如果收入降到 0,就不会再减少了。 6. 小慕到达一座城市后的第二天才能开始卖唱。。 问贪心的小慕最多可以赚多少钱?
这类题属于华为 OD 机考真题方向中「200分 / 2024E」方向的高频题型,通常考察对「200分 / 2024E」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
第一行两个数字 T 和 N,中间用空格隔开,T 代表总天数;
N 代表路上经过 N 座城市;
0 < T < 1000,0 < N < 100
第二行 N+1 个数字,中间用空格隔开,代表每两座城市之间耗费的时间,其总和<=T。
接下来 N 行,每行两个数字 M 和 D,中间用空格隔开。代表每个城市的收入预期。
0 < M < 1000,0 < D < 100
一个数字。代表歌手最多可以赚多少钱。以回车结束
示例 1
输入示例
10 2 1 1 2 120 20 90 10
输出示例
540
总共 10 天,路上经过 2 座城市。 路上共花 1+1+2=4 天。 剩余 6 天最好的计划是在第一座城市待 3 天,在第二座城市待 3 天。 在第一座城市赚的钱:120 + 100 + 80 = 300 在第二座城市赚的钱:90 + 80 + 70 = 240 共 300 +240 = 540
示例 2
输入示例
10 3 1 1 2 3 120 20 90 10 100 20
输出示例
320
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
题目的名字已经把这道题用的算法告诉你了——贪心。
题干非常长,得好好理解题意。
首先歌手能够卖唱的所有天数是固定的。假设总时间为 T,花费在路上的时间数组为 days,那么可以停下来卖唱的时间为 X = T - sum(days)。这是很容易分析出来的结论。
那么为了能够赚更多的钱,我们一定要把 X 天都拉满,即尽可能地停留在某个城市赚钱。
这 X 天的分配实际上是任意的,停留在哪一个城市都行,只要停留够 X 天就肯定能赚到尽可能多的钱。实际上我们并不需要按照歌手的时间线来考虑问题,而是按照某一天能够在哪个城市获得的钱数最多来考虑问题的。
考虑例子: 停留的卖唱天数 X = 3,第一个城市的起始金额 M1 = 100,衰减速度 D1 = 50,第二个城市的起始金额 M2 = 80,衰减速度 D1 = 40。我们会做如下分析:
那么 X = 3 就用完了,最多可以赚 ans = 100 + 80 + 50 = 230。
虽然真正的时间线为 1(两天) -> 2(一天),但是分析问题时我们的过程是 1(一天) -> 2(一天) -> 1(一天),但也能够计算出正确的答案。
上述过程涉及到动态维护最大值的情形,很显然可以使用优先队列来维护该过程。具体过程如下:
1. 构建一个以最大值为排序依据的优先队列(即大根堆)heap 2. 将每一个城市的 (M, D) 储存在堆中。 3. 循环 X 次,表示最多可以停留 X 天在进行卖唱。
ans += MM -= D4. 注意在循环中,必须判断 heap 的长度是否大于 0。如果等于 0,说明优先队列中无元素,所有的城市赚的钱都衰减到 0 了,此时可以直接退出循环。
不熟悉优先队列的同学,每一次最大值挑选完衰减后再次插入原数组的操作,也可以直接用排序的 API 来完成。由于插入完毕后至多只有一个元素是无序的,加上 N 的最大值只有 100,因此这里直接使用排序并不会比优先队列慢很多。
复杂度分析 设 N 为城市数,X = T - sum(days) 为扣除路程后可用来卖唱的总天数。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有