二维单调栈
http://poj.org/problem?id=3494
题意:给出一个01矩阵,问最大的全为1的子矩阵。
解法:将预处理后,将每一列(行)看成一维单调栈。
//#include<bits/stdc++.h>
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std ;
typedef long long ll ;
const int N = 2010, M = 200010 ;
int n , m ;
int a[N][N];
int st[N] , top ;
int b[N];
int len[N];
int work(){
top = 0 ;
int cnt = 0 ;
for(int i = 0 ; i < m ; i++) len[i] = 1 ;
for(int i = 0 ; i < m ; i++){
cnt = 0 ;
while(top && b[i] <= b[st[top]]){
len[st[top]] += cnt ;
cnt = len[st[top]] ;
top--;
}
len[i] += cnt ;
st[++top] = i ;
}
cnt = 0 ;
while(top){
len[st[top]] += cnt ;
cnt = len[st[top]] ;
top--;
}
int ans = 0 ;
for(int i = 0 ; i < m ; i++){
ans = max(ans , b[i]*len[i]);
}
return ans ;
}
void solve(){
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < m ; j++){
scanf("%d" , &a[i][j]);
}
}
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < m ; j++){
if(a[i][j] == 1){
if(i && a[i-1][j]){
a[i][j] += a[i-1][j] ;
}
}
}
}
int ans = 0 ;
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < m ; j++){
b[j] = a[i][j] ;
}
ans = max(ans , work());
}
cout << ans << endl;
}
signed main(){
#ifdef ONLINE_JUDGE
#else
freopen("D:\\c++\\in.txt", "r", stdin);
//freopen("D:\\c++\\out.txt", "w", stdout);
#endif
while(~scanf("%d%d" , &n , &m))
solve();
}

浙公网安备 33010602011771号