POJ3494Largest Submatrix of All 1’s[单调栈]

Largest Submatrix of All 1’s

Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 5883   Accepted: 2217
Case Time Limit: 2000MS

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 ≤ mn ≤ 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

2 2
0 0
0 0
4 4
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0

Sample Output

0
4

Source

POJ Founder Monthly Contest – 2008.01.31, xfxyjwf


最大全1子矩阵


对于每一行,维护一个全1高度(tot)递减栈就行了

注意0时tot[j]=-1,相当于一个高度为0的

最后依旧要弹出栈里的,如果没有上一行连sample都错

注意l已经包含了这个点,最后+n-st[top].pos不需要再+1

//
//  main.cpp
//  poj3494
//
//  Created by Candy on 10/5/16.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=2e3+5;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x;
}
int n,m,tot[N],a,ans=0;
struct data{
    int h,l,pos;
}st[N];
int top=0;
int main(int argc, const char * argv[]) {
    while(scanf("%d%d",&n,&m)!=EOF){
        ans=0;
        memset(tot,0,sizeof(tot));
        for(int i=1;i<=n;i++){
            top=0;
            for(int j=1;j<=m;j++){
                a=read();
                if(!a) tot[j]=-1;
                data t;
                t.h=++tot[j];t.l=1;t.pos=j;
                int right=0;
                while(top&&st[top].h>=t.h){
                    ans=max(ans,(st[top].l+right)*st[top].h);
                    //printf("%d %d %d  %d %d %d\n",i,j,ans,st[top].l,right,st[top].h);
                    right+=st[top].l; t.l+=st[top].l;
                    top--;
                }
                st[++top]=t;//printf("top %d\n",top);
            }//printf("toptop %d\n",top);
            while(top){
                ans=max(ans,st[top].h*(st[top].l +n-st[top].pos));
                //printf("p %d %d %d %d\n",st[top].h,st[top].pos,st[top].l,ans);
                top--;
            }
        }
        printf("%d\n",ans);
    }

    return 0;
}
时间: 2024-10-10 02:38:06

POJ3494Largest Submatrix of All 1’s[单调栈]的相关文章

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

题目: Largest Submatrix of All 1’s Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 5540   Accepted: 2085 Case Time Limit: 2000MS Description Given a m-by-n (0,1)-matrix, of all its submatrices of all 1’s which is the largest? By largest w

HDU 2870 Largest Submatrix (单调栈)

http://acm.hdu.edu.cn/showproblem.php?pid=2870 Largest Submatrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1569    Accepted Submission(s): 748 Problem Description Now here is a matrix wit

SPOJ MINSUB - Largest Submatrix(二分+单调栈)

http://www.spoj.com/problems/MINSUB/en/ 题意:给出一个n*m的矩阵M,和一个面积k,要使得M的子矩阵M'的最小元素最大并且面积大于等于k,问子矩阵M'的最小元素最大能是多少,并且求出最大的面积. 思路:二分一个最小元素x,转化为判断矩阵M里面是否存在一个子矩阵使得这个子矩阵的面积大于等于k并且所有元素都大于x. 用另一个矩阵,1表示该位置的元素大于等于x,0表示元素小于x. 转化为判断是否存在一个子矩阵元素为1的面积大于等于k. 这样可以用到早上学习的单调

spoj MINSUB 单调栈+二分

题目链接:点击传送 MINSUB - Largest Submatrix no tags You are given an matrix M (consisting of nonnegative integers) and an integer K.  For any submatrix of M' of M define min(M') to be the minimum value of all the entries of M'.  Now your task is simple:  fi

(转载)单调栈题目总结

POJ 2796 Feel Good 题意:给出一个长度为n(n<100000)的序列,求出一个子序列,使得这个序列中的最小值乘以这个序列的和的值最大. 思路:枚举每一个点,然后算出以这个点为最小值的区间能向左向右扩展到哪里,然后选择最优的就行. SOJ 3085: windy's cake V 题意:和POJ2796一样,只是不要求输出子序列的两个端点. 思路:粘贴上一题的代码就行 SOJ 3329: Maximum Submatrix II 题意:给出一个n*m的矩阵,求出这个矩阵的最大0矩

(单调栈)poj-2559 Largest Rectangle in a Histogram

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the

【单调栈】hdu1506 Largest Rectangle in a Histogram

单调栈的介绍及一些基本性质 http://blog.csdn.net/liujian20150808/article/details/50752861 依次把矩形塞进单调栈,保持其单增,矩形中的元素是一个三元组,存储其位置,高度,以及以其为高度的情况下,大矩形的左边界最多扩展到哪里. 每次将新的元素塞进栈的时候,其左边界就是其左侧第一个小于它的矩形的位置+1. 然后,每个矩形出栈的时候,记录其右边界为当前往栈里面塞的矩形的位置-1,然后更新答案即可. 注意最后把所有的矩形出栈,更新答案. #in

BZOJ 3238 AHOI 2013 差异 后缀数组+单调栈

题目大意: 思路:一看各种后缀那就是后缀数组没跑了. 求出sa,height之后就可以乱搞了.对于height数组中的一个值,height[i]来说,这个值能够作为lcp值的作用域只在左边第一个比他小的位置到右边第一个比他小的位置.这个东西很明显可以倍增RMQ+二分/单调栈. 之后就是数学题了 Σlen[Ti] + len[Tj] = (len + 1) * len * (len - 1),之后吧所有求出来的Σ2 * lcp(Ti,Tj)减掉就是答案. 记得答案开long long CODE:

51nod 1215 数组的宽度&amp;poj 2796 Feel Good(单调栈)

单调栈求每个数在哪些区间是最值的经典操作. 把数一个一个丢进单调栈,弹出的时候[st[top-1]+1,i-1]这段区间就是弹出的数为最值的区间. poj2796 弹出的时候更新答案即可 #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath