贪心-插空-5831. 你可以工作的最大周数

2021-08-01 22:01:47

问题描述:

给你 n 个项目,编号从 0 到 n - 1 。同时给你一个整数数组 milestones ,其中每个 milestones[i] 表示第 i 个项目中的阶段任务数量。

你可以按下面两个规则参与项目中的工作:

每周,你将会完成 某一个 项目中的 恰好一个 阶段任务。你每周都 必须 工作。
在 连续的 两周中,你 不能 参与并完成同一个项目中的两个阶段任务。
一旦所有项目中的全部阶段任务都完成,或者仅剩余一个阶段任务都会导致你违反上面的规则,那么你将 停止工作 。注意,由于这些条件的限制,你可能无法完成所有阶段任务。

返回在不违反上面规则的情况下你 最多 能工作多少周。

 

示例 1:

输入:milestones = [1,2,3]
输出:6
解释:一种可能的情形是:
​​​​- 第 1 周,你参与并完成项目 0 中的一个阶段任务。
- 第 2 周,你参与并完成项目 2 中的一个阶段任务。
- 第 3 周,你参与并完成项目 1 中的一个阶段任务。
- 第 4 周,你参与并完成项目 2 中的一个阶段任务。
- 第 5 周,你参与并完成项目 1 中的一个阶段任务。
- 第 6 周,你参与并完成项目 2 中的一个阶段任务。
总周数是 6 。
示例 2:

输入:milestones = [5,2,1]
输出:7
解释:一种可能的情形是:
- 第 1 周,你参与并完成项目 0 中的一个阶段任务。
- 第 2 周,你参与并完成项目 1 中的一个阶段任务。
- 第 3 周,你参与并完成项目 0 中的一个阶段任务。
- 第 4 周,你参与并完成项目 1 中的一个阶段任务。
- 第 5 周,你参与并完成项目 0 中的一个阶段任务。
- 第 6 周,你参与并完成项目 2 中的一个阶段任务。
- 第 7 周,你参与并完成项目 0 中的一个阶段任务。
总周数是 7 。
注意,你不能在第 8 周参与完成项目 0 中的最后一个阶段任务,因为这会违反规则。
因此,项目 0 中会有一个阶段任务维持未完成状态。
 

提示:

n == milestones.length
1 <= n <= 105
1 <= milestones[i] <= 109

问题求解:

周赛第二题,最初的考虑是使用优先队列维护一下,但是发现在最后的几个case上一直过不去,就知道这条路是条死路。

实际上,本题是一个完全贪心求解的问题,重要的是要分析得到一个很重要的点:耗时最长的任务如果能够被完成,那么所有的任务都能被完成。

原因如下:

举例[5, 2, 1],5,5,5,5,5中有5 + 1 = 6个空,如果能将5完全分隔开,那么后面的数字只需要从头开始继续插入即可。

那么什么情况下能够将最大的数字完全分隔开呢?

显然对于剩余的所有数字,其间隔为rest + 1,如果maxn <= rest + 1,那么就可以将最大的数字完全分隔开来,在这种情况下,所有的数字都能被满足;

如果maxn > rest + 1,那么最大的数字没有办法被完全分隔,因此最终的结果是rest * 2 + 1。

 

class Solution:
    def numberOfWeeks(self, milestones: List[int]) -> int:
        maxn = max(milestones)
        total = sum(milestones)
        rest = total - maxn
        if maxn > rest + 1:
            return rest * 2 + 1
        else:
            return total

 

  

 

posted @ 2021-08-01 22:02  hyserendipity  阅读(74)  评论(0编辑  收藏  举报