hihoCoder #1157 建造金字塔

这道题我想了一天才想清楚做法。AC 了之后去看别人写的题解,都是三言两语意识流式描述,我并不能读懂。我觉得很自卑,为何人家解这道题如此轻松。不过,我还是决定把我的解法写下来,并且一定要写清楚。


思路

我想多数人见到这个题目的想法都是:先按照某种方式对三角形排序,再设法 DP 。大方向确实如此。我的做法是:「以三角形底边的右端点坐标为第一关键字从小到大,以三角形底边的左端点坐标为第二关键字从大到小」排序。记排序后的 $n$ 个三角形为:$T_1, T_2, dots, T_n$ ,如此排序使得:

  1. 所有被 $T_i$ 覆盖且不与 $T_i$ 重合的三角形都排在 $T_i$ 前面
  2. 设 $0 le k< j < i le n$ 且 $T_j otsubseteq T_i, T_k otsubseteq T_i$ 那么 $(T_k cap T_{i}) subseteq (T_j cap T_i)$

我不清楚是否还有别的排序方法也能满足上面两个条件,不过其他排序方法只要满足上述两性质,都可进而采用下面要讲的 DP 方法。

DP 状态 $DeclareMathOperator{DP}{DP}$

$DP_i$ 表示「只在前 $i$ 个金字塔(即三角形)中选择一些建造并且一定建造第 $i$ 座金字塔,所能获得的最大收益」。

边界条件

为了方便我们定义第 $0$ 座金字塔为 $(-infty, 0, 0)$ 。
边界条件为 $DP_0 = 0$ 。

转移方程

$$
DP_i = max left{ DP_j + sum_{j< k< i, T_k subseteq T_i} T_k.w + T_i.w - left | T_i ight | + left| T_j cap T_i ight| ight} quad (0 le j <i, T_j otsubseteq T_i)
$$

$left| T ight|$ 表示(等腰直角)三角形 $T$ 的 面积。

复杂度 $O(N^2)$ 。

这就是我的思路,当然还可以做一些小优化。代码就不贴了,我的目标是把思路说清楚,思路清楚了,代码并不难写。

总结

这道题目应当算作简单题,虽然我解得并不轻松。这个问题中,三角形其实可以简化为底边所表示的线段,设底边长为 $l$,则三角行面积 $s$ 可表为 $s = s(l) =l^2/4$ 。这个问题可一般化为:给定若干条 $x$ 轴上的线段,每条线段有一个收益值,另外给出一个成本函数 $cost(l)$ 。其他部分和原具体问题相似,不赘述。

原文地址:https://www.cnblogs.com/Patt/p/7612068.html