二维单调栈
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(); }