UVA12170 轻松爬山 Easy Climb 题解

发布时间 2024-01-06 08:12:58作者: Pengzt

UVA12170

7 月份的题了,补一补。场上写挂了一点还是很遗憾的。

容易想到 dp。

但是由于值域非常大,直接 dp 是不行的。但是 \(n\) 非常小,容易想到离散化。

但是离散化后是不能直接加减的。有用的数值初看是有 \(\mathcal{O}(n^2d)\) 的,即 \(h_i + kd(k\in(-n+1, n))\),这肯定是不行的。但是通过观察可以发现这个东西肯定有一种方案存在 \(i, j\) 使得最终所有高度都能用 \(h_i+jd\) 的方法表示出来。

这其实是很容易想到的,感性的想一下,后面有一个很高的 \(j\),使得 \(i \sim j\) 之间的山峰需要递增的话,第 \(j - 1\) 座山一定是 \(h_i + kd\)\(h_j - d\),因为如果是 \(h_i + kd +\Delta\) 且这个数与任意的 \(h_j\) 的差均不是 \(d\) 的倍数时,它一定有更优的方法被 \(h_j + kd\) 表示出来,即 \(\Delta\) 是没有必要的,比如两个相邻的高度差为 \(H(H>d)\) 的山峰一定是变化 \(kd+H \bmod d\) 的,再变就不优了。而 \(\mid k\mid_{max} = n-1\) 的原因是 \(\mid h_n - h_1\mid\) 最多就是 \((n-1)d\),否则一定无解。

想到这里之后,dp 就是简单的了。

\(f_{i, j}\) 表示前 \(i\) 座山,高度为 \(b_j\) 时的最小花费,其中 \(b\) 为离散化后的数组。

\(f_{i, j} = \min\limits_{|b_j - b_k| \le m}\{f_{i - 1, k} + |a_i - b_j|\}\)

这样转移的复杂度太高,显然可以使用单调队列优化至 \(\mathcal{O}(n^3)\)

最后的答案是显而易见的:\(ans = f_{n, i}(b_i=a_n)\)

时间复杂度:\(\mathcal{O}(n^3)\)

空间复杂度:\(\mathcal{O}(n^2)\)

代码非常好写,就不放了。