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; }