zoukankan      html  css  js  c++  java
  • [单调栈] Jzoj P4260 最大子矩阵

    Description

    我们将矩阵A中位于第i行第j列的元素记作A[i,j]。一个矩阵A是酷的仅当它满足下面的条件:
           A[1,1]+A[r,s]<=A[1,s]+A[r,1](r,s>1)
    其中r为矩阵A的行数,s为矩阵A的列数。
    进一步,如果一个矩阵是非常酷的仅当它的每一个至少包含两行两列子矩阵都是酷的。
    你的任务是,求出一个矩阵A中的一个非常酷的子矩阵B,使得B包含最多元素。
     

    Input

    第一行包含两个整数R,S(2<=R,S<=1000),代表矩阵的行数与列数。
    接下来R行每行包括S个整数,代表矩阵中的元素,矩阵中元素的绝对值不大于1000000。

    Output

    一行一个整数,代表子矩阵B的元素总数。如果没有一个非常酷的子矩阵,输出0。
     

    Sample Input

    输入1:
    3 3
    1 4 10
    5 2 6
    11 1 3
    输入2:
    3 3
    1 3 1
    2 1 2
    1 1 1
    输入3:
    5 6
    1 1 4 0 3 3
    4 4 9 7 11 13
    -3 -1 4 2 8 11
    1 5 9 5 9 10
    4 8 10 5 8 8

    Sample Output

    输出1:
    9
    输出2:
    4
    输出3:
    15
    【样例3解释】
        在第三个样例中,子矩阵B的左上角为A[3,2],右下角为A[5,6]。
     

    Data Constraint

    对于60%的数据,满足R,S<=350。
    对于100%的数据,满足2<=R,S<=1000,矩阵中元素的绝对值不大于1000000。

    题解

    • 对于一个矩阵为酷只为它的每一个2*2的矩阵都是酷的
    • 那么可以考虑求出每一个2*2的矩阵是否酷,把酷的矩阵染为颜色1,不酷的矩阵不染色
    • 那么现在问题就转换为求一个含有最大面积的长方形(含1)
    • 用单调栈解决就好了

    代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 int r,s,a[1010][1010],k[1010][1010],cnt,w[1010],ans;
     6 int main()
     7 {
     8     scanf("%d%d",&r,&s);
     9     for (int i=1;i<=r;i++)
    10         for (int j=1;j<=s;j++)
    11             scanf("%d",&a[i][j]),k[i][j]=1;
    12     for (int j=2;j<=s;j++)
    13         for (int i=2;i<=r;i++)
    14             if (a[i][j]+a[i-1][j-1]<=a[i-1][j]+a[i][j-1]) k[i][j]=k[i-1][j]+1;
    15     for (int i=1;i<=r;i++)
    16         for (int j=1;j<=s;j++) 
    17             if (k[i][j]==1) k[i][j]=0;
    18     w[0]=1;
    19     for (int i=2;i<=r;i++)
    20     {
    21         cnt=0;
    22         for (int j=2;j<=s;j++)
    23         {
    24             while (cnt&&k[i][j]<=k[i][w[cnt]])
    25             {
    26                 ans=max(ans,k[i][w[cnt]]*(j-w[cnt-1]));
    27                 cnt--;
    28             }
    29             w[++cnt]=j;
    30         }
    31         while (cnt)
    32         {
    33             ans=max(ans,k[i][w[cnt]]*(s+1-w[cnt-1]));
    34             cnt--;
    35         }
    36     }
    37     printf("%d",ans);
    38     return 0;
    39 }
  • 相关阅读:
    学生管理系统(3:添加查询界面)
    Django模块笔记【六】
    Django模块笔记【五】
    Django模块笔记【四】
    Django模块笔记【三】
    Django模块笔记【二】
    Django模块笔记【一】
    网络编程基础【CSS编程】
    Django入门笔记【六】
    Django入门笔记【五】
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9296250.html
Copyright © 2011-2022 走看看