您的位置:首页 > 其它

POJ 3494 Largest Submatrix of All 1's(最大全1子矩阵面积、单调栈)

2016-07-25 23:53 393 查看
题目链接:

POJ 3494 Largest Submatrix of All 1’s

题意:

给出一个n∗m的01矩阵,求出最大全1子矩阵面积。

数据范围:n,m≤2000

分析:

我们把每一行单独处理,把从这行向上连续延伸全为1的最大长度看成是矩形的高,那么每行其实就是求个最大矩形面积。

height[i][j]:第i行第j列元素往上最长的连续1长度

需要用O(n2)的复杂度预处理出height[],然后需要枚举每行,每行利用单调栈可以在O(n)复杂度得到最大矩形面积,总的时间复杂度是:O(n2)。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long ll;
const int MAX_N = 2010;

int n, m, ans;
int mat[MAX_N][MAX_N];
int height[MAX_N][MAX_N], sta[MAX_N], L[MAX_N], R[MAX_N];

//height[i][j]:第i行第j列元素往上最长的连续1长度
//维护单调非递减栈
void solve(int row)
{
int top = 0, cur;
height[row][m + 1] = 0;
for (int j = 1; j <= m + 1; ++j) {
while (1) {
cur = sta[top];
if (height[row][cur] <= height[row][j]) break;
R[cur] = j;
--top;
}
L[j] = cur;
sta[++top] = j;
}
for (int j = 1; j <= m; ++j) {
if(mat[row][j] == 0) continue;
int len = R[j] - L[j] - 1;
ans = max(ans, height[row][j] * len);
//  printf("height[%d][%d] = %d len = %d\n", row, j, height[row][j], len);
}
}

int main()
{
while (~scanf("%d%d", &n, &m)) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
scanf("%d", &mat[i][j]);
}
}
memset (height, 0, sizeof(height));
for (int j = 1; j <= m; ++j) {
for (int i = 1; i <= n; ++i) {
if (mat[i][j] == 1) {
height[i][j] = 1;
while (mat[++i][j] == 1) {
height[i][j] = height[i - 1][j] + 1;
}
--i;
}
}
}
ans = 0;
for (int i = 1; i <= n; ++i) { solve(i); }
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  POJ 单调栈