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要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着‘F‘并且面积最大。
但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。

Input

第一行两个整数N,M,表示矩形土地有N行M列。
接下来N行,每行M个用空格隔开的字符‘F‘或‘R‘,描述了矩形土地。

Output

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

Sample Input

5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F

Sample Output

45

HINT

对于50%的数据,1<=N,M<=200

对于100%的数据,1<=N,M<=1000

思路:遍历枚举以1-n行为底的最大矩阵,利用单调栈O(n)求一个数最小值的左边和右边;

   枚举以该点为最小值的最大区间为r-l+1;详见代码;

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 100000007
#define esp 0.00000000001
const int N=1e3+10,M=1e6+10,inf=1e9+10;
int a[N][N];
int getnum(int x,int y)
{
    int num=0;
    for(int i=x;i>=1;i--)
    {
        if(a[i][y]==0)
        break;
        num++;
    }
    return num;
}
int b[N];
int l[N];
int r[N];
int d[N];
int main()
{
    int x,y,z,i,t;
    while(~scanf("%d%d",&x,&y))
    {
        for(i=1;i<=x;i++)
        for(t=1;t<=y;t++)
        {
            char ch;
            cin>>ch;
            if(ch==‘F‘)
            a[i][t]=1;
        }
        int ans=0;
        for(i=1;i<=x;i++)
        {
            for(t=1;t<=y;t++)
            b[t]=getnum(i,t);
            b[0]=b[y+1]=-1;
            int k=0;
            d[++k]=0;
            for(t=1;t<=y;t++)
            {
                while(b[d[k]]>=b[t])k--;
                l[t]=d[k];
                d[++k]=t;
            }
            k=0;
            d[++k]=y+1;
            for(t=y;t>=1;t--)
            {
                while(b[d[k]]>=b[t])k--;
                r[t]=d[k];
                d[++k]=t;
            }
            for(t=1;t<=y;t++)
            ans=max(ans,(r[t]-l[t]-1)*b[t]);
        }
        printf("%d\n",3*ans);
    }
    return 0;
}
时间: 2024-10-15 06:29:32

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

BZOJ 1057: [ZJOI2007]棋盘制作 悬线法求最大子矩阵+dp

1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳.而我们的主人公小Q,正是国际象棋的狂热爱好者.作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则.小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一.小Q想在这种纸中裁减

UVALive 3029 City Game 悬线法求最大子矩阵面积 dp

题目链接:点击打开链接 Bob is a strategy game programming specialist. In his new city building game the gaming environment is as follows: a city is built up by areas, in which there are streets, trees, factories and buildings. There is still some space in the a

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 1057 ZJOI 2007 棋盘制作 DP+悬线法

题目大意:给出一个由01形成的矩阵,问这个矩阵中最大面积的正方形和矩形,其中任意一个方块相邻的都是不同的格子. 思路:其实吧所有(i + j)&1的位置上的数字异或一下,就变成都是0或者都是1的最大正方形和矩形了.第一问就是水DP,第二问可以单调栈或者悬线.都很好写. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define

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

题意:链接 方法:最大子矩阵之算♂法② 解析: 首先这道题单调栈DP是肯定能过的,但是一点都不高端! 什么年代了还用这种方式! 所以如何彰显自己是个高端的人呢? 悬线法能满足你的需求! 什么是悬线法? 首先对于悬线的定义,对于一个n*m的坐标图中的任意一点,其向上能延伸的一个线段(不碰到坏点)称为悬线. 如果定义h[i,j]代表(i,j)该点的悬线长度. 那么,如果其上方的点是坏点,则悬线长度为0,该点为坏点,悬线长度为0,否则的话,为上方的点的悬线长度加1. 如果这么统计的话,那么最终的悬线长

BZOJ 3039: 玉蟾宫【dp】

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

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]); 还有可以处理出来符

【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 1057: [ZJOI2007]棋盘制作( dp + 悬线法 )

对于第一问, 简单的dp. f(i, j)表示以(i, j)为左上角的最大正方形, f(i, j) = min( f(i + 1, j), f(i, j + 1), f(i + 1, j + 1)) + 1 (假如(i, j)和右边和下边不冲突) 第二问就是经典的悬线法解决最大子矩阵了, 维护悬线H[i][j], 左边右边延伸的最长距离.先一行一行求出这一行的L, R, 然后再从上往下扫, 维护H, L, R 写完我才发现我脑残了...最大的正方形一定是在最大子矩阵里面啊...所以其实不用dp.