标签:dp
在一个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
先统计出每一行的连续1个数
例如
1 1 1 1 1 0 1
0 0 1 1 0 1 1
0 0 1 1 1 0 1
1 1 0 0 1 0 0
得到
1 2 3 4 5 0 1
0 0 1 2 0 1 1
0 0 1 2 3 0 1
1 2 0 0 1 0 0
然后按照列累加得到连续
1 2 5 8 5 0 3
0 0 5 8 0 1 3
0 0 5 8 4 0 3
1 2 0 0 4 0 0
这个是通过与maxn进行比较看是否要算的
然后如果有需要算的话,那么就看这个位置往下和网上走,找到在第二个矩形的情况这一列中小于这个数的时候退出
因为这个数是统计的横向过来的1的个数
只有在大于等于自身的时候,才能以现在这个长度来构建1矩阵
所以得到代码如下
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int map[1005][1005]; int col[1005][1005]; int n,m,maxn; void set_col(int p) { int i,j,sum; for(i = 1; i<=n; i++) { if(!map[i][p]) continue; j = i; sum = 0; while(map[j][p] && j<=n) { sum+=map[j][p]; j++; } for(int k = i; k<j; k++) col[k][p] = sum; i = j; } } int find(int r,int c) { int i,j,val=map[r][c]; int cnt = 1; for(i = r-1; i>0; i--) { if(val>map[i][c]) break; cnt++; } for(i = r+1; i<=n; i++) { if(val>map[i][c]) break; cnt++; } return val*cnt; } int solve() { int i,j; maxn = 0; for(i = 1; i<=n; i++) { for(j = 1; j<=m; j++) { if(maxn<col[i][j] && map[i][j]) { int val = find(i,j); maxn = max(maxn,val); } } } return maxn; } int main() { int i,j; while(~scanf("%d%d",&n,&m)) { for(i = 1; i<=n; i++) { for(j = 1; j<=m; j++) scanf("%d",&map[i][j]); } for(i = 1; i<=n; i++) { for(j = 2; j<=m; j++) { if(map[i][j]==1 && map[i][j-1]) map[i][j]=map[i][j-1]+1; } } for(i = 1; i<=m; i++) set_col(i); printf("%d\n",solve()); } return 0; }
标签:dp
原文地址:http://blog.csdn.net/libin56842/article/details/41849769