洛谷 P4147 【玉蟾宫】悬线法解决最大子矩阵问题

新学的悬线法。。

本题的题意就是,在一个有障碍的矩形中寻找一个最大的不包含障碍的矩形。

直接枚举四条边界判断合法肯定是不行的,这样做起码是 O ( n 5 O(n^5 O(n5)的复杂度。
悬线法运用了贪心的思想,那就是对于每一个点,考虑他以某种方式所能形成的一个极大的矩形。

显然,一个极大矩形应该是上下左右都不能再向外扩充的矩形。悬线法利用了这个结论,考虑的是以每一个障碍物上边界为上边界的极大矩形。

如图所示, 1 1 1号矩形的上边界是本题的上边界, 2 2 2号矩形的上边界由向上方走遇到的第一个障碍决定, 3 3 3号矩形也是如此。

可以枚举下边界上的一个点来确定这个矩形的最大高度,也就是图中的1️⃣2️⃣3️⃣。当这个点向上没有碰到障碍或边界时矩形高度 + 1 +1 +1。高度确定了之后就可以由中间的行确定他的宽度。

对于每一个点,我们记录ta向上、向左、向右最多能扩充的长度。每个点所生成的极大矩形由包含它的最高的矩形决定【事实上和单调栈的思路有点类似】。

为什么这样能枚举到所有的极大矩形呢?

当枚举到1️⃣号点时,他对答案的贡献只有红色的矩形,但他其实同时也包含在绿色的矩形里面啊?

但是,很容易就会发现其实绿色的矩形在枚举2️⃣号点的时候就已经枚举到了。
这里极大矩形的高度和宽度是互相制约的,确定一个,再让另外一个尽量大就好了。

代码部分,首先需要预处理出每个点向上向左向右的最长距离:

const int MAXN = 1017;
int n, m;
int G[MAXN][MAXN];
int up[MAXN][MAXN];
int l[MAXN][MAXN];
int r[MAXN][MAXN];

for(int i = 1; i <= n; i++)
        for
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值