题目大意:
给出一个由0,1组合的矩阵,试求出元素最多且都是1的矩形
题目思路:
求以第i行为底的最大矩形,利用单调队列或者单调栈,以单调队列为例:
对该行中的每个点的高度为最小基准向左右两边进行松弛,求其可满足的左右区间的最大区间。
以右区间为例:
从该行的右端点开始一次进队遍历,建立单调增的队列将队尾与当前点的高度进行比较,若大于等于,则队尾出队,否则队尾元素的下标便是以当前点高度为最小高度的矩形的右区间最大值+1.
左区间同理亦可得到,从而确定该点所决定的矩形的大小,进而却定以该行为底的最大矩形
具体的可以看这个博客:https://blog.csdn.net/baimu1893/article/details/101671633
#include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #define LL long long #define INF 0x3f3f3f3f #define ls nod<<1 #define rs (nod<<1)+1 const double eps = 1e-10; const int maxn = 2e3 + 10;; const LL mod = 1e9 + 7; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; int cnt; int q[maxn]; int f[maxn],g[maxn]; int a[maxn][maxn]; int main() { int n,m; while (~scanf("%d%d",&n,&m)) { for (int i = 1;i <= n;i++) { a[i][0] = a[i][m+1] = -1; for (int j = 1;j <= m;j++) scanf("%d",&a[i][j]); } for (int i = 2;i <= n;i++) { for (int j = 1;j <= m;j++) if (a[i][j]) a[i][j] = a[i-1][j] + a[i][j]; } int ans = -1; for (int k = 1;k <= n;k++) { cnt = 1; q[1] = m + 1; for (int i = m;i >= 1;i--) { while (cnt && a[k][q[cnt]] >= a[k][i]) cnt--; f[i] = q[cnt]-i-1; q[++cnt] = i; } cnt = 1; q[1] = 0; for (int i = 1;i <= m;i++) { while (cnt && a[k][q[cnt]] >= a[k][i]) cnt--; g[i] = i-q[cnt]-1; q[++cnt] = i; } for (int i = 1;i <= m;i++) { int v = (f[i] + g[i] + 1) * a[k][i]; if (v > ans) ans = v; } } printf("%d ",ans); } return 0; }