Mayflyyh
Mayflyyh
MayFlyyh's Blog
题解 LuoGu P4147 玉蟾宫 最大子矩阵问题 悬线法 学习笔记

题解 LuoGu P4147 玉蟾宫 最大子矩阵问题 悬线法 学习笔记

题目描述

这片土地被分成N*M个格子,每个格子里写着’R’或者’F’,R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。

现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着’F’并且面积最大。

但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。

输入格式:
第一行两个整数N,M,表示矩形土地有N行M列。

接下来N行,每行M个用空格隔开的字符’F’或’R’,描述了矩形土地。

输出格式:
输出一个整数,表示你能得到多少银子,即(3*最大’F’矩形土地面积)的值。

本题要求 最大子矩阵面积

O(N^3^)

暴力做法,枚举每个点,每个点向下的宽度,每个点向右的长度,比较

TLE

O(N^2^) 悬线法

考虑这样一个问题,在一个点,向左右不断延伸直到无法延伸

对这一行连续的点进行该操作

那么对于这一行连续的点来说,向左向右延伸的和相同

说明矩阵的长度已经确定,现在需要确定宽度

再不断向上延伸,但是为了保证矩形,所以长度变成了向上延伸的每行的宽度的最小值

如图:

http://t1.aixinxi.net/o_1c8707apce507pp2sfl0c1uj8a.jpg-j.jpg

那么再来思考一个问题,一个点在向上拓展的过程中,可能由于上一行的宽度比现在的宽度小,那么等于为了高度舍弃了一定宽度,为什么会算出最大矩形呢?

如图:http://t1.aixinxi.net/o_1c870iske5scl71nhl4pokepa.jpg-j.jpg

答案是不会的,矩形的确定与拓展的高度有关。

如果对每个点都进行该操作,那么图中的绿色点得到的矩形就是紫色矩形,

只用在最后比较每个点拓展的矩形的面积大小即可

这就是悬线法,知道了原理后总结一下:

对每个点向左向右拓展的宽度,再算出向上拓展的高度

计算每个点组成的矩形面积

比较一下答案

总结一下

因为是矩形,最好的复杂度好不过N^2^

N^3^的做法通常是算出的结果有重复,每个点算了多次

N^2^可以使每个点只算一遍,减少了非比较重复计算

代码:

#include<bits/stdc++.h>
int LL[1001][1010],RR[1001][1010],HH[1001][1010];
int a[1010][1010];
int ans=0;
int main (){
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
            char x=' ';
            while(x==' '||x=='\n')scanf("%c",&x);
            if(x=='F'){
                a[i][j]=1;
                HH[i][j]=HH[i-1][j]+1;
                LL[i][j]=LL[i][j-1]+1;
            }
        }
    for(int i=1;i<=n;++i)
        for(int j=m;j>=1;--j){
            if(a[i][j]){
                RR[i][j]=RR[i][j+1]+1;
        }
    }
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
            if(LL[i-1][j]>0){
                LL[i][j]=std::min(LL[i-1][j],LL[i][j]);
                RR[i][j]=std::min(RR[i-1][j],RR[i][j]);
            }
            ans=std::max(ans,(LL[i][j]+RR[i][j]-1)*HH[i][j]);
        }
    printf("%d",ans*3);
}
本文链接:http://www.mayflyyh.com/archives/163
知识共享许可协议
本文采用CC BY-NC-SA 3.0进行许可。
首页      DP      题解 LuoGu P4147 玉蟾宫 最大子矩阵问题 悬线法 学习笔记
http://0.gravatar.com/avatar/6cc3a2831375e487976e09c80dfcb52e?s=256&d=monsterid&r=g

MayFlyyh

文章作者

Oier

发表评论

textsms
account_circle
email

MayFlyyh's Blog

题解 LuoGu P4147 玉蟾宫 最大子矩阵问题 悬线法 学习笔记
题解 LuoGu P4147 玉蟾宫 最大子矩阵问题 悬线法 学习笔记 题目描述 这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予…
扫描二维码继续阅读
2018-03-10