题目
分析
乍一看,这是一道模拟算法题。但实际上,这是一个贪心(加上差分)的题目。我们先按照样本数据做一个小范围的模拟,如下表所示:
天数 | 深度1 | 深度2 | 深度3 | 深度4 | 深度5 | 深度6 |
---|---|---|---|---|---|---|
0(初始) | 4 | 3 | 2 | 5 | 3 | 5 |
1 | 3 | 2 | 1 | 4 | 2 | 4 |
2 | 2 | 1 | 0 | 3 | 1 | 3 |
3 | 1 | 0 | 0 | 3 | 1 | 3 |
4 | 0 | 0 | 0 | 3 | 1 | 3 |
5 | 0 | 0 | 0 | 2 | 0 | 2 |
6 | 0 | 0 | 0 | 1 | 0 | 2 |
7 | 0 | 0 | 0 | 0 | 0 | 2 |
8 | 0 | 0 | 0 | 0 | 0 | 1 |
9 | 0 | 0 | 0 | 0 | 0 | 0 |
根据题意,我们肯定选择最浅的那个位置作为突破口:因为它最浅,所以可以从头到尾地进行施工,也可以从头到尾地减少深度1。这么做两天后,深度3变为了0,不可避免地出现了断点。我们对断点两侧进行同样的操作——因为两侧操作是独立的,所以先进行哪里无所谓——直到第9天可以全部清零。
(听起来有点分治的味道?!)
从左到右继续观察,各个点的的深度:
- 对于任意一个位置,它的深度\(depth[i]\)决定了它最终是需要这么多天来填满的。但这填满的过程,可以是独立进行(左右都填满了),也可以在填满一个区间时,“顺手”填一下。
- 如果
i
点深度大过i-1
的深度,那么i
点肯定要比i-1
点晚填满。晚几天呢?就是这两点的深度之差:\(depth[i]-depth[i-1]\)。这个天数是实实在在要进行施工的,对最后工期有实在影响(有“贡献”)。 - 反之,我们不用考虑
i
点需要花几天填满,因为在填i-1
的时候用了\(depth[i-1]\)天,也顺便将这个点填满了,也就是说这个点i
对最后工期没有影响(没有“贡献”)。
以上就是核心算法。
看到\(depth[i]-depth[i-1]\)这样的表达式,我们知道这是一个有关差分的题目了。
我们看下对应原始数组的差分数组:
原数组 4 3 2 5 3 5
差分 4 -1 -1 3 -2 2
如果我们将其中正的差分相加,正好就是9
,也就是最后的答案。
答案
思考
也许,这道题目的描述可以再生动一些:
春春每天可以选择一段连续区间[L,R],填充这段区间中的每块区域,让其下陷深度减少1。
改成:
春春每天可以选择一段连续区间[L,R],在这个区间中的每块区域,放下一个高度为1的水泥块,让其下陷深度减少1,但不能让某个地块高出地面。