最大全0/1子矩阵的探究

by MedalPluS

【问题模型】

给定一个n*n的矩阵,求矩阵中面积最大的一个值全是0或1的子矩阵

【分析】

(这里n*n完全可以改为n*m,但由于种种原因,等下代码里是n*n)

首先很容易想到一种解法,枚举这个子矩阵的左上方,和右下方,然后暴力统计,这样时间复杂度O(N6),这种做法很广泛

这肯定是不能满足我们的需求,那么应该怎么办呢?我们发现O(n2)的时间浪费在统计上,我们可以使用前缀和的手段,预处理

这样时间复杂度O(n4),还是很垃圾

在暴力种种优化都不行的时候,想一想贪心或者数学或者DP把!——无名氏

贪心:这肯定是不对的

DP:转移方程太难推出

数学:这个我可以

对于3*3的矩阵

0 1 1

1 0 0

1 1 1

求全1矩阵

我们可以逐行算!

比如说设f(i)表示第i列的已经连续的全1的子矩阵的长度

处理第一行,可以发现f(1)=0,f(2)=1,f(3)=1

映射到数轴上,可以发现是这样的:

面积最大全1矩阵很明显是1+1=2,记录下来,发现了没?其实就是直方图最大面积

继续处理第二行,此时f(1)=1,f(2)=0,f(3)=0

映射到数轴上,可以发现是这样的:

最大面积为1,而没有原来的2小,所以不记录

处理第三行,此时f(1)=2,f(2)=1,f(3)=1

映射到数轴上

轻易地算出最大面积为3,比2大,更换

扫描结束,最大值为3,而正好是答案

【实现】

那么具体应该如何实现呢?

同上,设f(),再设l(),r(),表示第i行以f(i)为最大值的直方图的左端点l(i)和右端点r(i)

显然,这行的结果为f(i)*((r(i)-l(i)+1)

每次累计最大值

输出即可

【代码】

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4
 5 const int maxn=2001;
 6
 7 int a[maxn][maxn],n,ans;
 8 int l[maxn],r[maxn],b[maxn];
 9
10 int main(){
11     int i,j;
12     scanf("%d",&n);
13     for(i=1;i<=n;i++){
14       for(j=1;j<=n;j++){
15         scanf("%d",&a[i][j]);
16         if(!a[i][j])b[j]++;//注意这里指的是全0子矩阵,如果是求全1子矩阵的话,应该改为if(a[i][j])b[j]++;想想为什么
17         else b[j]=0;
18       }
19       for(j=1;j<=n;j++)//求出l
20       {
21         l[j]=j;
22         while(l[j]-1>=1 && b[l[j]-1]>=b[j])
23           l[j]=l[l[j]-1];
24       }
25       for(j=n;j>=1;j--)//求出r
26       {
27         r[j]=j;
28         while(r[j]+1<=n && b[r[j]+1]>=b[j])
29           r[j]=r[r[j]+1];
30       }
31       for(j=1;j<=n;j++)//算出面积
32         if(b[j] && ans<b[j]*(r[j]-l[j]+1))
33           ans=b[j]*(r[j]-l[j]+1);
34     }
35     printf("%d",ans);
36     return 0;
37 }

转载于:https://www.cnblogs.com/maopengsen/p/4430775.html

最大全0/1子矩阵的探究相关推荐

  1. 单调栈求全1(或全0)子矩阵的个数 洛谷P5300与或和 P3400仓鼠窝

    爆零好爽,被中学生虐好爽,还好我毕业得早 求全1(或全0)子矩阵的个数,看了题解有好几种思路,我学了三种,但有两种不是很理解,而且也没另外那个跑得快,所以简单讲述一一下我会的那种来自Caro23333 ...

  2. cv1159 最大全0子矩阵(极大子矩阵)

    题目描述 Description 在一个01方阵中找出其中最大的全0子矩阵,所谓最大是指0的个数最多. 输入描述 Input Description 输入文件第一行为整数N,其中1<=N< ...

  3. Python课程大全(0基础就该这样学)

    小甲鱼-<零基础入门学习Python> 000愉快的开始 001我和Python的第一次亲密接触 002用Python设计第一个游戏 003小插曲之变量和字符串 004改进我们的小游戏 0 ...

  4. 最大子矩阵问题悬线法 学习小结

    最近在写dp的题目 但是我这个同学又又又又生病了 学习了一下多叉树的背包问题和最大子矩阵的问题,还有攒了几道期望,先总结一下矩阵问题: 问题模型: 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点 ...

  5. 最大子矩阵问题悬线法 学习笔记

    学习材料:王知昆<浅谈用极大化思想解决最大子矩阵问题> [最大子矩阵问题] 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的.轮廓与整个矩形平行或重合的最大子矩形. [定义子矩形] ...

  6. CSS3单词及属性大全

    CSS3属性大全 0~9text:文本; /**/decoration:装饰,修饰; /**/none:没有,无,没有东西地; /**/list:列表; /**/style:样式; /**/persp ...

  7. python我的世界给予物品指令_我的世界给予物品指令大全 | 手游网游页游攻略大全...

    发布时间:2015-11-19 我的世界命令方块指令大全 我的世界命令方块怎么用.我的世界命令方块都有哪些攻能?我的世界命令方块怎么使用?下面99单机网小编给大家带来我的世界命令方块指令大全. /gi ...

  8. vim gvim技巧大全

    vim&gvim技巧大全(0)  很多东东都对于深入认识vim有很大帮助:) ---------------------------------------- # 基础 ----------- ...

  9. 稳压、调压、监控、DC/DC电路大全

    稳压.调压.监控.DC/DC电路大全 0 推荐 M5172L 零点起弧温度控制电路 有零点同步脉冲发生电路.差动放大电路.脉冲发生电路构成的温度控制电路:工作交流电源电压范围90-110mVrms(5 ...

最新文章

  1. 70.nodejs操作mongodb
  2. 自动驾驶多目视觉感知
  3. yum安装mysql步骤及报错ERROR 1045 (28000)
  4. 字节、快手、阿里、腾讯这两年的广告推荐技术进展 | AICon
  5. 一些面试题(JAVA)
  6. nginx用户权限问题
  7. 我的Go+语言初体验——go【Format】goplus
  8. 1976年,提出公钥密码体制概念的学者
  9. 2019年3月前端面试题
  10. Matlab向量与多项式
  11. [转].NET 开源项目 Anet 介绍
  12. JAVA做一个五星评论打分字体,java中的Font
  13. Qt ToolBar工具栏里同时显示图标和文字
  14. 随输入动态改变ui_深入详解 Jetpack Compose | 优化 UI 构建
  15. mysql的配置以及后端数据库的连接
  16. (转)Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
  17. C语言编写贪吃蛇小游戏
  18. jdk32位安装包下载_Win10离线安装.NET Framework 3.5方法汇总(附下载)
  19. Linux系统工具sar查看主机性能指标(内存、CPU、IO)
  20. java 去除数组中重复的元素

热门文章

  1. 用VS Express 2010开发第一个应用程序
  2. table 隔列换色
  3. WIN7无法记住远程登录密码
  4. jquery跨域调用wcf
  5. 数据库三范式的理解(引用其他网友)
  6. 扫盲行动之九:Vi编辑器的基本使用方法!
  7. Linq To Xml学习 - 1.LINQ to XML 概述
  8. Sigmoid 函数(To be continued)
  9. android文件存储token,ANDROID 学习笔记(二) 用户登陆问题 TOKEN SESSION 缓存
  10. openjdk linux tomcat,linux下配置安装OpenJDK+Tomcat(示例代码)