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

来源:互联网 发布:mac的免费游戏 编辑:程序博客网 时间:2024/04/29 07:21

题目链接:
POJ 3494 Largest Submatrix of All 1’s
题意:
给出一个nm的01矩阵,求出最大全1子矩阵面积。
数据范围:n,m2000
分析:
我们把每一行单独处理,把从这行向上连续延伸全为1的最大长度看成是矩形的高,那么每行其实就是求个最大矩形面积。

height[i][j]:ij1

需要用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;}
0 0
原创粉丝点击