给你一个长、宽均为 \(T\) 的网格图,左下角坐标为 \((0,0)\),右上角坐标为 \((T,T)\)。现在图上面有 \(n\) 个点(一定在格点上),你需要选择一些点,使得你选择的点按 \(x\) 从小到大排序后 \(y\) 也单调上升。最大化选的点的数量;在此基础上,让排序好的相邻的两点形成的矩形的面积之和最小。输出最小面积和。\(T\leqslant 10^6,N\leqslant 2\times 10^5\)。
首先,对于最大化选点的数量,这可以看作按 \(x\) 排好序之后求一遍 LIS。为了方便,我们把按 \(x\) 排完序的点重编号,以后认为 \(i<j\) 等价于 \(x_i<x_j\)(题目保证了不存在两个点使得 \(x\) 或 \(y\) 相等)。我们设 \(l_i\) 为以 \(i\) 结尾的 LIS 的长度。
第二问比较明显还需要 dp 求解,为了保证选的点数最多,我们只能在 \(l\) 值相差为 \(1\) 的点之间进行转移。具体地,设 \(f[i]\) 为选择了以 \(i\) 为结尾的 \(l_i\) 个点矩形面积和的最小值,那么转移显然: \[ f[i]=\min_{l_i=l_j+1,j<i,y_j<y_i}f[j]+(x_i-x_j)(y_i-y_j) \] 这样就有了一个 \(O(n^2)\) 的朴素算法。
这个东西可能看起来有一些像斜率优化,但是并不行,因为拆开括号以后既有 \(x_iy_j\) 项又有 \(x_jy_i\) 项,斜率优化做不了这个。
我们考虑另外一个优化办法——决策单调性。我们先把括号拆开: \[ f[i]=\min_{l_i=l_j+1,j<i,y_j<y_i}f[j]+x_iy_i-x_iy_j-x_jy_i+x_jy_j \] 假设现在有两个决策点 \(j,k\ (j<k)\),正在进行决策的是 \(i\),那么 \(j\) 比 \(k\) 优当且仅当 \[ f[j]+x_iy_i-x_iy_j-x_jy_i+x_jy_j\leq f[k]+x_iy_i-x_iy_k-x_ky_i+x_ky_k\\ f[j]-x_iy_j-x_jy_i+x_jy_j\leq f[k]-x_iy_k-x_ky_i+x_ky_k\\ (y_k-y_j)x_i+(x_k-x_j)y_i\leq f[k]-f[j]+x_ky_k-x_jy_j \] 我们注意到,对于两个 \(l\) 相同的点 \(j,k\),若 \(x_j<x_k\),那么一定有 \(y_j>y_k\)。因为如果依旧有 \(y_j<y_k\) 那么 \(l_k\) 就可以从 \(l_j\) 转移过来,它们的 \(l\) 就不相等了。反过来同理。
那么如果我们把 \(x_i\),\(y_i\) 看作变量,那么 \(j\) 比 \(k\) 优的情况对应了坐标系里的一个半平面(也就是不等式的解集),而且因为我们钦定 \(j>k\),那么这个半平面一定长这个样子
其中蓝色为解集部分,解集一定是一条斜率为正的直线的下方。那么要更新的点一定被这条直线分为了两部分。那么如果在 \(i\) 时,\(j\) 比 \(k\) 优(即点 \(i\) 在蓝色区域内),那么对于 \(u>i\),\(j\) 也一定比 \(k\) 优。这样的话对于一组 \(l\) 相同的询问,他们的最优决策位置一定是单调不增的。这就可以决策单调性了。
注意一下上面的分析都忽略了 \(x\) 和 \(y\) 的限制,那么如何满足呢?注意到对于任何一个点,可行的决策点都是一个区间,所以对每一排开一个线段树,线段树分治一下,把询问丢到所有符合要求的区间内,这样如果一个询问被挂在了某个区间内,区间内的点都可以转移到它,最后把答案取 \(\max\) 就好了。如果以分治或者二分+单调队列计算决策单调性,总的复杂度为 \(O\left(n(\log^2n+\log T)\right)\)。
需要特殊注意的是每次计算一个区间时,不要直接和 \(f[mid]\) 比较,需要再开一个变量记录只包含这段区间中的决策点时的最小值,要不然有时已经算过的 \(f[mid]\) 比整个区间的决策都优,这样就会错误。
代码:
1 |
|