二维单调栈

http://poj.org/problem?id=3494

题意:给出一个01矩阵,问最大的全为1的子矩阵。

解法:将预处理后,将每一列(行)看成一维单调栈。

//#include<bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SC scanf
#define rep(i , j , n) for(int i = j ; i <= n ; i++)
#define red(i , n , j)  for(int i = n ; i >= j ; i--)
#define INF  0x3f3f3f3f
#define mod 1000000007
#define PI acos(-1)
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
typedef long long ll ;
const int maxn = 1e4;
int a[maxn][maxn];
int b[maxn] , len[maxn];
int s[maxn] , top ;
int n , m  , ans ;

void work(){
    b[m+1] = -INF , top = 0 ;
    int temp = 0;
    rep(i , 1 , m+1){
        while(top && b[s[top-1]] >= b[i]){
            len[s[top-1]] += temp ;
            temp = len[s[top-1]];
            ans = max(ans , temp * b[s[top-1]]);
            top--;
        }
        len[i] += temp ;
        temp = 0;
        s[top++] = i ;
    }
}

void init(){
    ans = 0 ;
}
int main()
{
    while(cin >> n >> m){
        init();
        rep(i , 1 , n){
            rep(j , 1 , m){
                scanf("%d" , &a[i][j]);
            }
        }
        rep(j , 1 , m){
            red(i , n , 2){
                if(a[i-1][j]){
                    a[i-1][j] += a[i][j];
                }
            }
        }
        rep(i , 1 , n){
            rep(j , 1 , m){
                b[j] = a[i][j];
                len[j] = 1 ;
            }
            work();
        }
        cout << ans << endl;
    }

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/nonames/p/12317495.html