zoukankan      html  css  js  c++  java
  • 51Nod 1158 全是1的最大子矩阵 —— 预处理 + 暴力枚举 or 单调栈

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1158

    基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
     收藏
     关注
    给出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的。输出M2的面积。
     
    Input
    第1行:2个数m,n中间用空格分隔(2 <= m,n <= 500)
    第2 - N + 1行:每行m个数,中间用空格分隔,均为0或1。
    Output
    输出最大全是1的子矩阵的面积。
    Input示例
    3 3
    1 1 0
    1 1 1
    0 1 1
    Output示例
    4

    题解:

    POJ2559 加强版,预处理一下以每个格子作为底,最多可以往上延伸多少个格子,这样就可以把这些连续的格子看成一根柱子,如果按行枚举,那么就转化成了POJ2559的问题了,即利用单调栈,当然这题也可以直接暴力枚举。

    暴力枚举:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 using namespace std;
    13 typedef long long LL;
    14 const int INF = 2e9;
    15 const LL LNF = 9e18;
    16 const int MOD = 1e9+7;
    17 const int MAXM = 1e5+10;
    18 const int MAXN = 5e2+10;
    19 
    20 int a[MAXN][MAXN];
    21 int main()
    22 {
    23     int n, m;
    24     while(scanf("%d%d",&m,&n)!=EOF)
    25     {
    26         for(int i = 1; i<=n; i++)
    27         for(int j = 1; j<=m; j++)
    28         {
    29             scanf("%d",&a[i][j]);
    30             if(a[i][j]) a[i][j] += a[i-1][j];
    31         }
    32 
    33         int ans = 0;
    34         for(int i = 1; i<=n; i++)
    35         for(int j = 1; j<=m; j++)
    36         {
    37             int w = a[i][j];
    38             ans = max(ans, w*1);
    39             for(int k = j+1; k<=m; k++)
    40             {
    41                 w = min(w,a[i][k]);
    42                 ans = max(ans, w*(k-j+1));
    43             }
    44         }
    45         printf("%d
    ", ans);
    46     }
    47 }
    View Code

    单调栈:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 using namespace std;
    13 typedef long long LL;
    14 const int INF = 2e9;
    15 const LL LNF = 9e18;
    16 const int MOD = 1e9+7;
    17 const int MAXM = 1e5+10;
    18 const int MAXN = 5e2+10;
    19 
    20 int h[MAXN][MAXN];
    21 int Stack[MAXN][2], top;
    22 int main()
    23 {
    24     int n, m;
    25     while(scanf("%d%d",&m,&n)!=EOF)
    26     {
    27         for(int i = 1; i<=n; i++)
    28         for(int j = 1; j<=m; j++)
    29         {
    30             scanf("%d",&h[i][j]);
    31             if(h[i][j]) h[i][j] += h[i-1][j];   //预处理出高度,这样就可转化为POJ2559了
    32         }
    33 
    34         int ans = 0;
    35         for(int i = 1; i<=n; i++)
    36         {
    37             top = 0;
    38             h[i][m+1] = -1;     //在最后加个很小的值,就能把栈里的元素全部倒出来了
    39             for(int j = 1; j<=m+1; j++)
    40             {
    41                 int len = 0;    //长度
    42                 while(top && Stack[top-1][0]>=h[i][j])  //如果当前高度小于等于
    43                 {
    44                     len += Stack[top-1][1];     //长度累加
    45                     ans = max(ans,Stack[top-1][0]*len);
    46                     top--;
    47                 }
    48                 Stack[top][0] = h[i][j];    //当前元素入栈
    49                 Stack[top++][1] = len+1;    //把出栈了的元素的长度都累加到入栈元素当中去
    50             }
    51         }
    52 
    53         printf("%d
    ", ans);
    54     }
    55 }
    View Code
  • 相关阅读:
    《自拍教程17》Python调用命令
    c和c++学哪个?
    PHP:变量之效果域、静态变量,常量等基础知识
    Java中NIO及基础实现
    零代码=零门槛?
    程序员真的都比较宅吗?
    DataGridView怎样完成添加、删除、上移、下移一行
    C# 控件 RichTextBox 显示行号,而且与Panel彼此联动
    C语言代码中的空白符表示什么
    php 中的4种标记风格介绍
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8759490.html
Copyright © 2011-2022 走看看