Loading

Cover the Grid 题解

简要题意

给出一个 \(n\times n\) 的网格,其中 \(m\) 个格子被染黑。以网格左下角为原点,底边为 \(x\) 轴,左边为 \(y\) 轴,向右、向上为正方向,建立平面直角坐标系。每次可以选择网格下底边的一段区间 \([l,r]\)\(0\leq l<r\leq n\) ),盖住以线段 \((l,0),(r,0)\) 为底边,第一象限内的等腰直角三角形,并花费 \(r-l\) 的代价。

对于 \(k=1,2,\dots,n\) ,求在代价总和不超过 \(k\) 的情况下,最终所能覆盖的黑色面积最大值 \(S_k\) 。为了方便,依次输出 \(4S_1,4S_2,\dots,4S_n\)

题解

我们记 \(T_{l,r}\) 为以线段 \((l,0),(r,0)\) 为底边,第一象限内的等腰直角三角形,\(t_{l,r}\)\(T_{l,r}\) 所盖住的黑色部分面积。

首先说明一个简单的小结论:我们不会选出重叠的两个三角形。因为如果我们选择了\(T_{a,b},T_{c,d}\)\(a\leq c\leq b\leq d\),我们耗费了 \((b-a)+(d-c)\) 的代价。而如果将两个三角形替换为 \(T_{a,d}\) ,那么代价变为 \(d-a\leq (b-a)+(d-c)\) ,同时 \(T_{a,d}\) 完全覆盖了 \(T_{a,b}\)\(T_{c,d}\) ,所以选择重叠的三角形必然不优。

那么就不难得到一个时间复杂度为 \(O(n^3)\)\(\mathrm {dp}\) 做法:设 \(f_{i,j}\) 为当前所选的三角形右顶点不超过 \(i\) ,总代价为 \(j\) 覆盖的最大黑色面积,那么转移为:

\[\begin{align*} f_{i,j}=\max\{\max_{l=1}^j\{f_{i-l,j-l}+t_{i-l,i}\},f_{i-1,j}\} \end{align*} \]

我们发现,\(i-j=(i-l)-(j-l)\) ,这说明我们可以将 \(i-j\) 相同的 \(f_{i,j}\) 分别独立计算。

从小到大枚举 \(d=i-j\) ,记 \(g_i=f_{i+d,i}\) ,其中 \(i=1,2,\dots,n-d\) 。将 \(g_i\) 初值设为 \(f_{i+d-1,i}\) 后,就可以将原问题转化为 \(n\) 个(也有可能是 \(n-1\) 个)独立的动态规划问题,并将 \(d\) 看作常数。状态转移方程:

\[\begin{align*} g_i=\max_{j=0}^{i-1}\{g_j+t_{j+d,i+d}\} \end{align*} \]

经过一番挖掘,我们可以发现一个优秀的性质:对于 \(i<j<k<l\) ,若 \(g_i+t_{i+d,k+d}\geq g_j+t_{j+d,k+d}\) ,则 \(g_i+t_{i+d,l+d}\geq g_j+t_{j+d,l+d}\) ,换句话说,如果 从 \(i\) 转移到 \(k\) 比从 \(j\) 转移到 \(k\) 更优,那么对于 \(k\) 之后的每个 \(l\) ,从 \(i\) 转移到 \(l\) 也比从 \(j\) 转移到 \(l\) 更优。原因也很浅显:\(T_{i+d,l+d}\setminus T_{i+d,k+d}\) (这两个三角形的“差”)完全地覆盖了 \(T_{j+d,l+d}\setminus T_{j+d,k+d}\)

这样,我们得到了一个类似决策单调性的性质,那么也尝试用类似处理决策单调性的方式优化它。

在我们遍历 \(i\) 来计算 \(g\) 的同时,我们维护一个栈 \(st\),栈中每个元素有两个属性 \((x,r)\),分别表示所记录决策点 \(x\),以及 \(x\) 可能影响到的最远位置 \(r\),记栈顶元素为 \(tp\)。每次我们遍历到 \(i\) 时,依次进行以下操作:

  1. \(tp.r<i\) 时,说明 \(tp.x\) 对于 \(g_i\) 必然不优,将栈顶弹出,直到 \(tp.r\geq i\) 或栈为空。
  2. 此时,由我们维护的栈的意义,直接由 \(g_{tp.x}\) 转移到 \(g_i\)
  3. 接下来,我们要将 \(i\) 加入栈中。首先,对于 \(i,tp.x\),二分出一个位置 \(p\),使得由 \(i\) 转移到 \(p\) 优于 由 \(tp.x\) 转移到 \(p\)(即 \(g_i+t_{i+d,p+d}>g_{tp.x}+t_{tp.x+d,p+d}\) ),同时由 \(i\) 转移到 \(p+1\) 不优于 由 \(tp.x\) 转移到 \(p+1\)。因为我们之前得到的性质,这说明对于 \(i+1,i+2,\dots,p\) 内的 \(j\),由 \(i\) 转移到 \(j\) 比由 \(tp.x\) 转移到 \(j\) 更好,而且 \(p+1\) 之后的 \(j\) 相反。此时如果有 \(p\geq tp.r\),说明 \(tp\) 再无用武之地,所以弹出栈顶。
  4. 重复 \(3\) 之中的过程,直到此时栈为空或栈顶 \(tp\) 满足 \(tp.r>p\)。这时,我们就可以将 \((i,p)\) 加入栈中,并保持栈内单调性。

这样,对于每个 \(d\),我们可以以 \(O(n\log n)\) 的时间复杂度计算出对应的 \(g\)

总时间复杂度 \(O(n^2\log n)\)

posted @ 2023-07-12 16:30  complexor  阅读(20)  评论(0)    收藏  举报