[51nod 1158 全是1的最大子矩阵] 单调栈
题目链接:[51nod 1158 全是1的最大子矩阵]
题意描述:给出
1
个
解题思路:可以把题目看成一个求二维最大矩形面积。用单调栈求出以第
i
#include <bits/stdc++.h>
using namespace std;
#define FIN freopen("input.txt", "r", stdin)
typedef __int64 LL;
const int MAXN = 500 + 5;
const int INF = 0x3f3f3f3f;
int N, M;
int G[MAXN][MAXN];
int H[MAXN];
struct SNode {
int v, left;
SNode() {}
SNode(int v, int left) : v(v), left(left) {}
} top;
stack<SNode> stk;
int process() {
int ret = 0;
while(!stk.empty()) stk.pop();
for(int j = 0; j < M; j++) {
int low = j;
while(!stk.empty() && (top = stk.top()).v > H[j]) {
ret = max(ret, top.v * (j - top.left));
low = min(low, top.left);
stk.pop();
}
stk.push(SNode(H[j], low));
}
while(!stk.empty()) {
top = stk.top();
ret = max(ret, top.v * (M - top.left));
stk.pop();
}
return ret;
}
int main() {
#ifndef ONLINE_JUDGE
// FIN;
#endif // ONLINE_JUDGE
while(~scanf("%d %d", &N, &M)) {
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
scanf("%d", &G[i][j]);
}
}
memset(H, 0, sizeof(H));
int ans = 0;
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
if(G[i][j]) H[j] ++;
else H[j] = 0;
}
ans = max(ans, process());
reverse(H, H + M);
ans = max(ans, process());
reverse(H, H + M);
}
printf("%d\n", ans);
}
return 0;
}