POJ 3494 Largest Submatrix of All 1’s

Description

Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is the largest? By largest we mean that the submatrix has the most elements.

Input

The input contains multiple test cases. Each test case begins with m and n (1 ≤ m, n ≤ 2000) on line. Then come the elements of a (0,1)-matrix in row-major order on m lines each with n numbers. The input ends once EOF is met.

Output

For each test case, output one line containing the number of elements of the largest submatrix of all 1’s. If the given matrix is of all 0’s, output 0.

Sample Input

  1. 2 2
  2. 0 0
  3. 0 0
  4. 4 4
  5. 0 0 0 0
  6. 0 1 1 0
  7. 0 1 1 0
  8. 0 0 0 0

Sample Output

  1. 0
  2. 4
  3.  
  4. 释意:
      给出一个由01组合的矩阵,试求出元素最多且都是1的矩形。 poj2559加强版。
    题解:
    1.将矩阵看成不同高度矩形,若相邻两行中若有1相邻则次矩形的高度便加1,将每一行分别看做矩形的底进行更新,从而问题变成了找面积最大矩形
    举例说明:
    因为我们要找的是矩形,所以它一定是以 某个行元素开始的,如果枚举行的时候,我们会发现:
    对于第一行: 

对于第二行:

第三行:

第四行: 

这样的话,其实我们要找到的某个矩形就转换成 一某一个行开始的 histogram的最大矩形问题了。

那么我们原始矩形可以变成如下的形式的数据:

第一行表示,我们以第一行作为底边,所形成的矩形的高度,其他行也类似。

2.求以第i行为底的最大矩形,利用单调队列或者单调栈,以单调队列为例:

对该行中的每个点的高度为最小基准向左右两边进行松弛,求其可满足的左右区间的最大区间。

以右区间为例:

从该行的右端点开始一次进队遍历,建立单调增的队列将队尾与当前点的高度进行比较,若大于等于,则队尾出队,否则队尾元素的下标便是以当前点高度为最小高度的矩形的右区间最大值+1.

左区间同理亦可得到,从而确定该点所决定的矩形的大小,进而却定以该行为底的最大矩形。

3.代码实现:

  1. //单调队列实现 C++提交 若用G++则会T!!!!!
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <cmath>
  7. #include <vector>
  8. #include <map>
  9. #include<string.h>
  10. #include<stack>
  11. #include<set>
  12. #include <queue>
  13. using namespace std;
  14. struct Node
  15. {
  16. int val;
  17. int position;
  18. }q[]; // 数组模拟单调递增队列
  19. int n,m;
  20. int l[]; // 以当前点高度为最小高度的矩形的左区间最大值
  21. int r[]; //以当前点高度为最小高度的矩形的右区间最大值
  22. int a[][];
  23. //求每一行的最大矩形
  24. int AREA(int nn)
  25. {
  26. int h = ; //队头
  27. int tail = ;//队尾
  28. //确定以每一个点的高度为最小值的矩形的右区间的最大值
  29. q[].position = n+;
  30. q[].val = -;
  31. for(int i = m;i>=;i--)
  32. {
  33. while(q[tail].val >= a[nn][i]) tail--;
  34. r[i] = q[tail].position-i;
  35. q[++tail].val = a[nn][i];
  36. q[tail].position = i;
  37. }
  38. //确定以每一个点的高度为最小值的矩形的左区间的最大值
  39. h = ;
  40. tail = ;
  41. q[].position = ;
  42. q[].val = -;
  43. for(int i = ;i<=m;i++)
  44. {
  45. while(q[tail].val>=a[nn][i]) tail--;
  46. l[i] = i-q[tail].position;
  47. q[++tail].val = a[nn][i];
  48. q[tail].position = i;
  49. }
  50. //该行中所有矩形的最大值
  51. int max1 = -;
  52. for(int i = ;i<=m;i++)
  53. max1 = max(max1,(l[i]+r[i]-)*a[nn][i]);
  54. return max1;
  55. }
  56. int main()
  57. {
  58.  
  59. while(~scanf("%d %d",&n,&m))
  60. {
  61. for(int i = ;i<=n;i++)
  62. for(int j = ;j<=m;j++)
  63. scanf("%d",&a[i][j]);
  64. //讲矩阵看做不同高度的矩形进行更新操作
  65. for(int i = ;i<=n;i++)
  66. for(int j = ;j<=m;j++)
  67. if(a[i][j]) a[i][j] = a[i-][j]+a[i][j];
  68. int max1 = -;
  69. //对每行进行遍历确定每行的最大矩形
  70. for(int i = ;i<=n;i++)
  71. max1 = max(AREA(i),max1);
  72. printf("%d\n",max1);
  73. }
  74. return ;
  75. }
  1. //单调栈实现
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <cmath>
  7. #include <vector>
  8. #include <map>
  9. #include<string.h>
  10. #include<stack>
  11. #include<set>
  12. #include <queue>
  13.  
  14. using namespace std;
  15. struct re
  16. {
  17. int h;
  18. int p;
  19. };
  20.  
  21. int m,n;
  22. int a[][];
  23. int h[][];
  24. int l[];
  25. int r[];
  26. int AREA(int R)
  27. {
  28. int i,j;
  29. int max1 = -;
  30. stack<re> s;
  31. //求左区间
  32. re p0,pi;
  33. p0.h = -;
  34. p0.p = -;
  35. s.push(p0);
  36. for(i = ;i<n;i++)
  37. {
  38. pi.p = i;
  39. pi.h = h[R][i];
  40. while(s.top().h>=pi.h) s.pop();
  41. l[i] = i-s.top().p;
  42. s.push(pi);
  43. }
  44. while(!s.empty()) s.pop();
  45. //求右区间
  46. p0.h = -;
  47. p0.p = n;
  48. s.push(p0);
  49. for(i =n- ;i>=;i--)
  50. {
  51. pi.p = i;
  52. pi.h = h[R][i];
  53. while(s.top().h>=pi.h) s.pop();
  54. r[i] = s.top().p-i;
  55. s.push(pi);
  56. }
  57. for(i = ;i<n-;i++)
  58. if((r[i]+l[i]-)*h[R][i]>max1)
  59. max1= (r[i]+l[i]-)*h[R][i];
  60. return max1;
  61. }
  62. int main()
  63. {
  64. int i,j;
  65. while(~scanf("%d%d",&m,&n))
  66. {
  67. for(i = ; i<m; i++)
  68. for(j = ; j<n; j++)
  69. {
  70. scanf("%d",&a[i][j]);
  71. h[i][j] = a[i][j];
  72. }
  73. for(i = ; i<n; i++)
  74. for(j = ; j<m; j++)
  75. if(h[j][i]) h[j][i] += h[j-][i];
  76. int max1 = -;
  77. for(i = ; i<m; i++) max1 = max(max1,AREA(i));
  78. printf("%d\n",max1);
  79. }
  80. }
  1. 本文为个人随笔,如有不当之处,望各位大佬多多指教.
    若能为各位博友提供小小帮助,不胜荣幸.

POJ 3494 Largest Submatrix of All 1’s 单调队列||单调栈的更多相关文章

  1. POJ - 3494 Largest Submatrix of All 1’s 单调栈求最大子矩阵

    Largest Submatrix of All 1’s Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is ...

  2. POJ 3494 Largest Submatrix of All 1’s(最大全1子矩阵)

    题目链接:http://poj.org/problem?id=3494 题意:给出一个01的矩阵,找出一个面积最大的全1矩阵. 思路:用h[i][j]表示从位置(i,j)向上连续1的最大长度.之后枚举 ...

  3. POJ 3494 Largest Submatrix of All 1’s

    POJ 2796 Feel Good HDU 1506 Largest Rectangle in a Histogram 和这两题一样的方法. #include<cstdio> #incl ...

  4. POJ 3494 Largest Submatrix of All 1’s(最大子图形)

    [题目链接] http://poj.org/problem?id=3494 [题目大意] 在01矩阵中求最大全1子矩形 [题解] 在处理每个点的时候,继承上一个点等高度下的左右最大扩展, 计算在该层的 ...

  5. POJ 2823 Sliding Window + 单调队列

    一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1)   从队首删除 (2)   从队尾删除 (3)   从队尾插入 (4)   ...

  6. [POJ2559&POJ3494] Largest Rectangle in a Histogram&Largest Submatrix of All 1’s 「单调栈」

    Largest Rectangle in a Histogram http://poj.org/problem?id=2559 题意:给出若干宽度相同的矩形的高度(条形统计图),求最大子矩形面积 解题 ...

  7. POJ-3494 Largest Submatrix of All 1’s (单调栈)

    Largest Submatrix of All 1’s Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 8551   Ac ...

  8. 第一周任务Largest Submatrix of All 1’s

    Largest Submatrix of All 1’s Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9512   Ac ...

  9. Largest Submatrix(动态规划)

    Largest Submatrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

随机推荐

  1. System.FormatException: GUID 应包含带 4 个短划线的 32 位数(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。解决办法

    查一下数据库的UID数据是否格式正确,如: 错误格式1: {E056BB36-D824-4106-A9C3-D8D8B9ADC1C 错误格式2: E056BB36-D824-4106-A9C3-D8D ...

  2. hdu-1856 More is better---带权并查集

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1856 题目大意: 一个并查集 计算每个集合的元素 找出元素最多的那个集合,输出元素的个数 解题思路: ...

  3. 【HHHOJ】NOIP模拟赛 玖 解题报告

    点此进入比赛 得分: \(100+20+100=220\)(还不错) 排名: \(Rank\ 16\) \(Rating\):\(+20\) \(T1\):[HHHOJ263]「NOIP模拟赛 玖」三 ...

  4. python_16_自己建立模块

    import python_5_password

  5. spring中@Autowrite注解和@Resource的区别

    spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...

  6. Linux网络编程之"获取网络天气信息"

    需求分析: 1.需要Linux c 网络编程基础, 2.需要了解 http 协议 3.需要天气信息相关api(可以从阿里云上购买,很便宜的!) 4.需要cJSON解析库(因为获取到的天气信息一般是用c ...

  7. 转:CentOS7 下 Redis4 安装与配置教程(Redis开机启动)

    转 https://ken.io/note/centos7-redis4-setup 一.前言 1.本教程主要内容 Redis安装与测试 Redis远程访问配置 Redis开机启动配置 2.本教程环境 ...

  8. jsp页面:一个form,不同请求提交form

    需求:一个表单中有一个请求 action="url"发送数据地址: 在表单外有一个请求,请求form表单提交的数据 我们用js来写:通过每次请求传不同的action=url; 例如 ...

  9. H5各种头部meta标签的功能

    <!DOCTYPE html>  H5标准声明,使用 HTML5 doctype,不区分大小写 <head lang=”en”> 标准的 lang 属性写法 <meta ...

  10. vue.js 二 路由懒加载

    当项目小的时候,我没考虑要去找这个得解决方案,也幸好现在几乎能迁移的项目都整合在了一个vue的项目里面 才发现编译后的vendor.js变得异常的大,而且几乎在项目每一个页面都需要加载这一个js,项目 ...