九度OJ 1497 面积最大的全1子矩阵 -- 动态规划
题目地址:http://ac.jobdu.com/problem.php?pid=1497
- 题目描述:
-
在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多。
- 输入:
-
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行是两个整数m、n(1<=m、n<=1000):代表将要输入的矩阵的大小。
矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开。
- 输出:
-
对应每个测试案例,输出矩阵中面积最大的全1子矩阵的元素个数。
- 样例输入:
-
2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0
- 样例输出:
-
0 4
#include <stdio.h> #include <string.h> #include <stdlib.h> #define max(a,b) (a > b ? a : b) #define min(a,b) (a < b ? a : b) #define MAXN 1001 int matrix[MAXN][MAXN]; int lagest_rectangle(/*int **matrix, */int m, int n) { int i, j; int *H = (int*) malloc(n * sizeof(int)); // 高度 int *L = (int*) malloc(n * sizeof(int)); // 左边界 int *R = (int*) malloc(n * sizeof(int)); // 右边界 int ret = 0; memset(H, 0, n * sizeof(int)); memset(L, 0, n * sizeof(int)); for (i = 0; i < n; i++) R[i] = n; for (i = 0; i < m; ++i) { int left = 0, right = n; // calculate L(i, j) from left to right for (j = 0; j < n; ++j) { if (matrix[i][j] == 1) { ++H[j]; L[j] = max(L[j], left); } else { left = j + 1; H[j] = 0; L[j] = 0; R[j] = n; } } // calculate R(i, j) from right to left for (j = n - 1; j >= 0; --j) { if (matrix[i][j] == 1) { R[j] = min(R[j], right); ret = max(ret, H[j] * (R[j] - L[j])); } else { right = j; } } } return ret; } int main() { int m, n; int i, j; while (scanf("%d%d", &m, &n) > 0) { for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { scanf("%d", &matrix[i][j]); } } printf("%d\n", lagest_rectangle(m, n)); } return 0; }
POJ上相似的题目:http://poj.org/problem?id=3494
参考资料:http://wenku.baidu.com/view/728cd5126edb6f1aff001fbb.html