BZOJ 3039 玉蟾宫 最大子矩阵 算♂法②

题意:链接

方法:最大子矩阵之算♂法②

解析:

首先这道题单调栈DP是肯定能过的,但是一点都不高端!

什么年代了还用这种方式!

所以如何彰显自己是个高端的人呢?

悬线法能满足你的需求!

什么是悬线法?

首先对于悬线的定义,对于一个n*m的坐标图中的任意一点,其向上能延伸的一个线段(不碰到坏点)称为悬线。

如果定义h[i,j]代表(i,j)该点的悬线长度。

那么,如果其上方的点是坏点,则悬线长度为0,该点为坏点,悬线长度为0,否则的话,为上方的点的悬线长度加1。

如果这么统计的话,那么最终的悬线长度应该为h[i,j]+1,不清楚自行观察。

然后呢对于一个悬线,我们欲知道最大子矩阵的大小的时候,需要将该悬线平移,即其向左能平移多长距离,向右能平移多长距离,不妨令l[i,j]为向左平移多少距离,r[i,j]为向右平移多长距离,便于统计,我们将坏点的这两种值置为0,非坏点的l为前1点+1,r为后一点+1,最终的l+r-1即为该矩阵的长,又悬线为宽,所以面积可以拿出。

但是怎么实现呢?

首先我们先假设所有的l,r都是对于本行的,那么很容易的就能处理出来所有点的l,r。复杂度2nm

之后我们枚举所有的非坏点,在更新h的同时,更新l,r,很容易发现,当前点的l应该是其上方的点的l与该点在其本行的l的较小者。不妨假设悬线长为2,那么随便画个图就能知道。悬线长大于2呢?又是个递归思想。

r的处理同理。

那么最终所有点的(h+1)*(l+r-1)就是该点对应的最大子矩阵面积。

可能有人会说,这样的话下边界不是最远距离啊?

但是别忘了,我们是按次序枚举的,也就是说,最远的下边界上的点我们一定会枚举到,在该点时便会更新。

这个算法与①有什么区别呢?

它的复杂度为n*m,在图较小的时候显然适合这种方法。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
using namespace std;
int l,w;
int h[N][N];
int le[N][N];
int ri[N][N];
int map[N][N];
char s[2];
int main()
{
    scanf("%d%d",&l,&w);
    for(int i=1;i<=l;i++)
    {
        for(int j=1;j<=w;j++)
        {
            scanf("%s",s);
            if(s[0]==‘F‘)map[i][j]=1;
        }
    }
    for(int i=1;i<=l;i++)
    {
        for(int j=1;j<=w;j++)
        {
            if(!map[i][j])
                le[i][j]=0;
            else le[i][j]=le[i][j-1]+1;
        }
        for(int j=w;j>=1;j--)
        {
            if(!map[i][j])
                ri[i][j]=0;
            else ri[i][j]=ri[i][j+1]+1;
        }
    }
    for(int i=1;i<=l;i++)
    {
        for(int j=1;j<=w;j++)
        {
            if(map[i-1][j]&&map[i][j])
            {
                h[i][j]=h[i-1][j]+1;
                le[i][j]=min(le[i][j],le[i-1][j]);
                ri[i][j]=min(ri[i][j],ri[i-1][j]);
            }
        }
    }
    int ans=0;
    for(int i=1;i<=l;i++)
    {
        for(int j=1;j<=w;j++)
        {
            ans=max(ans,(h[i][j]+1)*(le[i][j]+ri[i][j]-1));
        }
    }
    printf("%d\n",ans*3);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-08 03:23:09

BZOJ 3039 玉蟾宫 最大子矩阵 算♂法②的相关文章

bzoj 3039: 玉蟾宫 单调栈或者悬线法求最大子矩阵和

3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地.这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda.现在freda要在这里卖萌...它要找一块矩形土地,要求这片土地都标着'

BZOJ 3039: 玉蟾宫【dp】

Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地.这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda.现在freda要在这里卖萌...它要找一块矩形土地,要求这片土地都标着'F'并且面积最大.但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定

BZOJ 3039 玉蟾宫 悬线法

题目大意:给出一张地图,求出这张地图中最大的子矩阵,使得这个子矩阵不包含字母'R'. 思路:简单的悬线法求最大子矩阵,还是不带权值的,很好求.好久没写悬线了,复习一下. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1010 using namespace std; int m,n; bool map[MAX][M

BZOJ 3039 玉蟾宫

题意:求符合要求的最大子矩阵 首先,这道题单调栈可做,但我没有太明白,回头再补充. 另外,AC方法似乎不只有单调栈. 我们可以预处理出l[i][j]和r[i][j]表示(i,j)这个点在第i列向左和向右分别可以拓展到哪一个节点. 之后我们每次遍历到一个符合要求的点时,用它的上一排即L[i-1][j]和自己的l[i][j]更新出L[i][j] 即:L[i][j]=max(L[i-1][j],l[i][j]); 同理:R[i][j]=min(R[i-1][j],r[i][j]); 还有可以处理出来符

3039: 玉蟾宫

3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 512  Solved: 311[Submit][Status] Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地.这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda.现在freda要在这里卖萌...它要找一块

Vijos 1055 奶牛浴场 最大子矩阵 算♂法①

题意:链接 方法:最大子矩阵之算♂法① 解析: 首先谈到最大子矩阵,我们可能会想到之前做过的盖房子?,那道DP求解的题目. 然而这种题目当然有更高♂端的算法. 比如接下来要谈到的算法①. 我们先来观察数据范围,n,m<=30000,这下就玩完了,怎么dp? 一下子就D掉了你原来的算法,真是不留情面. 那么我们来介绍一种新的算法. 首先谈暴力,枚举各种坏点,但这种的复杂度呢?甚至可能达到6次方,所以怎么优化呢? 按照经验,这种坐标图排个序就能降下复杂度什么的. 于是有神犇介绍了s^2复杂度的算法,

【BZOJ-3039&amp;1057】玉蟾宫&amp;棋盘制作 悬线法

3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 444[Submit][Status][Discuss] Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地.这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda.现在freda要在这里卖

BZOJ_3039_玉蟾宫_(动态规划+悬线法)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3039 n*m的矩阵由R和F组成,求全是F的子矩阵的大小的三倍. 分析 悬线法: 浅谈用极大化思想解决最大子矩形问题--王知昆 l[x][y]表示点(x,y)在它那一行最多能扩展到左边的位置. r[x][y]表示点(x,y)在它那一行最多能扩展到右边的位置. 每一行分别预处理l与r. 在做dp的时候:如果点(x,y)可以取,那么h[x][y]=h[x-1][y]+1,l[x][y]=max(l

[BZOJ3039] 玉蟾宫

3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 574  Solved: 347[Submit][Status][Discuss] Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地.这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda.现在freda要在这里卖