题目
,我只在poj上找到了题目,usaco居然上不去。
大意就是说有一些\(1\times 1\times 1\)的小方块堆在一起,问最多能装多少水。
我们在一次测试中出了这题,由于我写水题的能力太弱,挂掉了。
算法1
这是我当时想到的方法。
我们可以统计出每一层能装多少水。由于层数达到了\(10^9\),所以需要离散化一下。
我们可以用并查集来维护装水的面积。
时间复杂度:\(O(n^2 \alpha (n^2))\)。
算法2
这是《算法艺术》\(P89\)上的例题(同时也是POI的原题!)。
书上的想法是从外往内维护边缘的方块的高度,根据“木桶效应”,我们从中选一个最矮的来往里面更新,这个可以用优先队列加快速度。
其实我觉得还可以这样思考:先令整个空间堆满水,除了在外围的方块。不妨设\(h(i,j)\)为位于\((i,j)\)的方块的高度,\(f(i,j)\)为可以装多少水。我们可以不断地迭代更新:如果\((x,y)\)与\((i,j)\)相邻,那么\(f(x,y) = max(h(x,y), f(i,j))\)。这样经过有限次数的迭代之后我们就得到了正确答案。当然,这样的效率是很低的,我们可以利用Dijkstra
Orz的思想,每次用\(f\)最小的去迭代其他的,由于它已经是最小的了,不可能再被人迭代了(这正是Dijkstra最短路的思想),所以我们每个点只需要去更新其他相邻的点一次。同样,我们也可以用优先队列来加快这一过程。
时间复杂度:\(O(n^2 \log n^2)\)。