Codevs 1159 最大全0子矩阵
在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多。
输入文件第一行为整数N,其中1<=N<=2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开。
输出文件仅一行包含一个整数表示要求的最大的全零子矩阵中零的个数。
5
0 1 0 1 0
0 0 0 0 0
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
9
https://wenku.baidu.com/view/cd82b3f5e87101f69f3195bc.html
/*
感觉很像“土豪聪要请客”,就用前缀和用同样的方法做了,结果超时
*/
#include<iostream>
#include<cstdio>
using namespace std;
int n,f[][],ans;
int main(){
//freopen("Cola.txt","r",stdin);
scanf("%d",&n);
int x;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
scanf("%d",&x);
f[i][j]=x^;
f[i][j]+=f[i][j-];
}
for(int i=;i<=n;i++){
for(int j=i;j<=n;j++){
int sum=,mx=;
for(int k=;k<=n;k++){
if(f[k][j]-f[k][i-]==(j-i+))sum++;
else sum=;
mx=max(mx,sum);
}
ans=max(ans,mx*(j-i+));
}
}
printf("%d",ans);
}
75分 前缀和TLE
学习材料:王知昆《浅谈用极大化思想解决最大子矩阵问题》
【最大子矩阵问题】
在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的、轮廓与整个矩形平行或重合的最大子矩形。
【定义子矩形】
有效子矩形:内部不包含障碍点的、轮廓与整个矩形平行或重合的子矩形。
极大子矩形:每条边都不能向外扩展的有效子矩形。
最大子矩形:所有有效子矩形中最大的一个(或多个)。
【极大化思想】
在一个有障碍点的矩形中最大子矩形一定是极大子矩形。
设计算法的思路:枚举所有的极大子矩形,找到最大子矩形。
设NM分别为整个矩形的长和宽,S为内部的障碍点数。
【算法1】
时间复杂度:O(S^) 空间复杂度:O(S)
由于极大子矩形的每一条边都不能向外扩展,那么极大子矩阵的每条边要么覆盖了障碍点,要么与整个矩形的边界重合
基本算法:枚举上下左右四个边界,然后判断组成的矩形是否是有效子矩形。
复杂度:O(S^) 可以改进的地方:产生了大量的无效子矩形。
初步改进的算法:枚举左右边界,然后对处在边界内的点排序,每两个相邻的点和左右边界组成一个矩形。
复杂度:O(S^) 可以改进的地方:枚举了部分不是极大子矩形的情况。
综上,设计算法的方向:
、保证每一个枚举的矩形都是有效的。
、保证每一个枚举的矩形都是极大的。
算法的过程:
枚举极大子矩形的左边界——>根据确定的左边界,找出相关的极大子矩形——>检查和处理遗漏的情况
()按照横坐标从小到大的顺序将所有的点编号为1,,...
()首先选取1号点作为要枚举的极大子矩形的左边界,设定上下边界为矩形的上下边界
()从左到右扫描,第一次到2号点,确定一个极大子矩形,修改上下边界;第二次找到3号点,以此类推。
()将左边界移动到2号点,3号点,,,以同样的方法枚举
遗漏的情况:
、矩形的左边界与整个矩形的左边界重合。解决方法:用类似的方法从左到右扫一遍
、矩形的左边界与整个矩形的左边界重合,且矩形的右边界与整个矩形的右边界重合。解决方法:预处理时增加特殊判断。
优点:利用的极大化思想,复杂度可以接受,编程实现简单。
缺点:使用有一定的局限性,不适合障碍点较密集的情况。
【算法2】
时间复杂度O(NM) 空间复杂度O(NM)
定义
有效竖线:除了两个端点外,不覆盖任何一个障碍点的竖直线段。
悬线:上端覆盖了一个障碍点或者到达整个矩形上边界的有效线段。
每个悬线都与它底部的点一一对应,矩形中的每一个点(矩形顶部的点除外)都对应了一个悬线。
悬线的个数=(N-)*M;
如果把一个极大子矩形按照横坐标的不同切割成多个与y轴平行的线段,那么其中至少有一个悬线。
如果把一个悬线向左右两个方向尽可能的移动,那么就得到了一个矩形,我们称它为悬线对应的矩形。
悬线对应的矩形不一定是极大子矩形,因为下边界可能还可以向下扩展。
设计算法:
原理:所有悬线对应矩形的集合一定包含了极大子矩形的集合。
通过枚举所有的悬线,找出所有的极大子矩形。
算法规模:
悬线个数=(N-)×M
极大子矩形个数≤悬线个数
具体方法:
设 H[i,j]为点(i,j)对应的悬线的长度。
L[i,j]为点(i,j)对应的悬线向左最多能够移动到的位置。
R[i,j]为点(i,j)对应的悬线向右最多能够移动到的位置。 !考虑点(i,j)对应的悬线与点(i-,j)对应的悬线的关系(递推思想): 如果(i-,j)为障碍点,那么,如图所示,(i,j)对应的悬线长度1,左右能移动到的位置是整个矩形的左右边界。
即 H[i,j]=,
L[i,j]=,R[i,j]=m 如果(i-,j)不是障碍点,那么,如图所示,(i,j)对应的悬线长度为(i-,j)对应的悬线长度+。
即 H[i,j]=H[i-,j]+ •如果(i-,j)不是障碍点,那么,如图所示,(i,j)对应的悬线左右能移动的位置要在(i-,j)的基础上变化。
L[i-,j]
L[i,j]=max
(i-,j)左边第一个障碍点的位置
•同理,也可以得到R[i,j]的递推式
R[i-,j]
R[i,j]=min
(i-,j)右边第一个障碍点的位置 优点: 复杂度与障碍点个数没有直接关系。
缺点:障碍点少时处理较复杂,不如算法1。 代码实现具体见WC2002 奶牛浴场(算法1)
codevs1159最大全0子矩阵(算法2)
学习资料(悬线法)
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 2010
int n,h[maxn],l[maxn],r[maxn];
int ans=,map[maxn][maxn];
int main(){
//freopen("Cola.txt","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&map[i][j]);
for(int i=;i<=n;i++)h[i]=,l[i]=,r[i]=n;
int ll,rr;
for(int i=;i<=n;i++){
ll=,rr=n+;
for(int j=;j<=n;j++){
if(map[i][j])h[j]=,l[j]=,ll=j;//遇到障碍
else h[j]++,l[j]=max(l[j],ll+);
}
for(int j=n;j>=;j--){
if(map[i][j])r[j]=n,rr=j;//遇到障碍
else r[j]=min(r[j],rr-),ans=max(ans,h[j]*(r[j]-l[j]+));
}
}
printf("%d",ans);
return ;
}
100分 悬线法
Codevs 1159 最大全0子矩阵的更多相关文章
- Codevs 1159 最大全0子矩阵 悬线法!!!!
1159 最大全0子矩阵 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O ...
- CODE[VS] 1159 最大全0子矩阵
写一道CODEVS的题目 其实我还是很喜欢CODEVS的界面的 主要是系统地学习一下悬线法这个看似十分简单,实际就是十分简单的算法 对于一些详细的东西参考dalao's blog,不喜勿喷 对于悬线法 ...
- [codevs1159]最大全0子矩阵(悬线法)
解题关键:悬线法模板题.注意此模板用到了滚动数组. #include<cstdio> #include<cstring> #include<algorithm> # ...
- 【DP/单调栈】关于单调栈的一些题目(codevs 1159,codevs 2673)
CODEVS 2673:Special Judge 题目描述 Description 这个月的pku月赛某陈没有参加,因为当时学校在考试[某陈经常逃课,但某陈还没有强大到考试也可以逃掉的程度].何 ...
- poj3494Largest Submatrix of All 1’s(最大全1子矩阵)
题目链接:http://poj.org/problem?id=3494 题目大意: 出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的. ...
- POJ 3494 Largest Submatrix of All 1’s(最大全1子矩阵)
题目链接:http://poj.org/problem?id=3494 题意:给出一个01的矩阵,找出一个面积最大的全1矩阵. 思路:用h[i][j]表示从位置(i,j)向上连续1的最大长度.之后枚举 ...
- [NOIP复习]第三章:动态规划
一.背包问题 最基础的一类动规问题.相似之处在于给n个物品或无穷多物品或不同种类的物品,每种物品仅仅有一个或若干个,给一个背包装入这些物品,要求在不超出背包容量的范围内,使得获得的价值或占用体积尽可能 ...
- BZOJ 1057 棋盘制作(最大01相间子矩阵)
求最大01相间子矩阵可以转换为求最大全0子矩阵.只需把棋盘(x+y)为奇数的取反,而该问题可以用经典的悬线法O(n^2)的求解. 悬线法呢. 首先定义b[i][j],为a[i][j]向上的最大连续0的 ...
- BZOJ1057 [ZJOI2007]棋盘制作
Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...
随机推荐
- JVM--内存区的划分
转自:http://www.jianshu.com/p/7ebbe102c1ae Java虚拟机在执行Java程序的过程中会把它管理的内存划分为若干个不同的数据区域. java虚拟机运行时数据区 一. ...
- systemclock sleep 睡眠
- Apache NiFi 开发 处理器使用说明
NIFI的使用: 注意:FlowFile由[属性]和[内容]组成,在解析的过程中这个概念非常重要,因为有些组件操作的是属性,有些组件操作的是内容,在配置组件时Destination配置项的选择很重要, ...
- PAT 天梯赛 L2-022. 重排链表 【数据结构】
题目链接 https://www.patest.cn/contests/gplt/L2-022 思路 先用结构体 把每个结点信息保存下来 然后深搜一下 遍历一下整个链表 然后就重新排一下 但是要注意一 ...
- make update-api
1) 添加系统API或者修改@hide的API后,需要执行 make update-api,然后再make 2) 修改公共api后,需要 make update-api 比较framework/ba ...
- Linux (ubuntu和redhat) 常用命令及细节
1.关闭防火墙(Ubuntu) sudo ufw disable 2.vi 拷贝 参考http://blog.sina.com.cn/s/blog_601331150100ecfr.html 一) ...
- 51Nod 1158 全是1的最大子矩阵 —— 预处理 + 暴力枚举 or 单调栈
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1158 1158 全是1的最大子矩阵 基准时间限制:1 秒 空 ...
- 多线程与Java的JMM内存模型
共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入时,能对另一个线程可见.从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存( ...
- RQNOJ 169 最小乘车费用:水dp
题目链接:https://www.rqnoj.cn/problem/169 题意: 给出行驶1-10公里的费用(所有车一样),可以倒车,问行驶n公里的最小费用. 题解: 大水题... (=´ω`=) ...
- RQNOJ 622 最小重量机器设计问题:dp
题目链接:https://www.rqnoj.cn/problem/622 题意: 一个机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得. w[i][j]是从供应商j处购得的部件i的重量, ...