题目描述
力扣:1953
给你
n
个项目,编号从 0 到 n - 1 。同时给你一个整数数组milestones
,其>中每个milestones[i]
表示第 i 个项目中的阶段任务数量。
你可以按下面两个规则参与项目中的工作:
- 每周,你将会完成 某一个 项目中的 恰好一个 阶段任务。你每周都 必须 工作。
- 在 连续的 两周中,你 不能 参与并完成同一个项目中的两个阶段任务。
一旦所有项目中的全部阶段任务都完成,或者仅剩余一个阶段任务都会导致你违反上面的规则,那么你将 停止工作 。注意,由于这些条件的限制,你可能无法完成所有阶段任务。
返回在不违反上面规则的情况下你 最多能工作多少周。
思路分析
很容易想到将 milestones
数组从大到小排列,从最大的milestones[0]
开始处理:
- 首先,不管采取遍历还是递归等,都应该先获取结束条件。不妨设当前最大值为
longest
,当前除最大值之外的其他值之和为res
。- 很明显当
longest
>res
, 依次用其他值来消耗最大值,结果应为2 * res + 1
。 - 当
longest
=res
, 结果应为2 * res
。
- 很明显当
- 现在就剩下
longest
<res
了,想办法将 将非结束条件向结束条件转换。- 本文的结束条件是
longest
>=res
, 怎么将非结束条件向结束条件转化呢,可以想到将res
减少即可。 - 思考
res
减少的可能性,如果res
中只有一个项目,显然不能减少,有两个以上的项目,那么将其中任意两个抵消即可。 - 题目再一次转化
res
中有几个项目。 因为最大值longest
<res
,所以res
中必然有两个以上项目,否则这个不等式就不成立。 - 通过上述分析,我们发现,本题目中非结束条件可以转化为结束条件。也就是说
longest
<res
也可以直接获取答案。 - 转化中,res中取任意两个抵消,每一次res都减去2, 那么有两种情况 减到
longest
=res
或longest
=res + 1
。而这两种情况下longest
和res
都可以被抵消处理,综上,这种情况下,所有项目中的任务都可以被处理,结果为longest
+res
。
- 本文的结束条件是
- 综上:当
longest
>res
结果为2 * res + 1
。 当longest
<=res
结果为longest
+res
。 - 过程优化:总体思考完后应进行过程优化,分析完后会发现排序过程是不必要的,只需要找出
longest
即可。
误区
- 处理
longest
<res
,想法是将longest抵消后换最大值,没有将其与结束条件联系起来。这种会发现处理过程极其麻烦。
借鉴与总结
- 不管是迭代还是递归,结束条件很重要
- 非结束条件向结束条件转换。不要没思考完全就写代码,这样转化过程可能只会看到片面,不能看到某些全局转化过程。