题目大意

给定一个m × n(0,1)矩阵,所有元素全为1的子矩阵中哪个最大?
例如:
2 * 2
0 0
0 0
输出:
0
////////////
4 * 4
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
输出:
4

解题思路:

最大子矩阵一定是矩阵中某个位置先向上连续元素1延伸,然后向左右延伸得到最大面积。
因此,我们可以现预处理数据,将所有点向上延伸连续1的长度设为高,然后利用单调栈,对每一行数据进行柱形图求最大子矩阵处理,然后每一行再比较大小就可以了,关于如何求柱形图最大子矩阵,可以参考博客
https://mp.csdn.net/mdeditor/101476806#

#include <iostream>
#include <cstring>
#include <stack> 
using namespace std;
int rec[2005][2005];
int h[2005][2005];
int main(){
	int m,n;
	while(cin>>m){
	    int maxArea=0;
		cin>>n;		
		for(int i=1;i<=m;i++)
		    for(int j=1;j<=n;j++)
		        cin>>rec[i][j];
    //预处理矩阵数据,统计每一个位置向上延续的最大高度 
		memset(h,0,sizeof(h));		
	    for(int i=1;i<=m;i++)
		    for(int j=1;j<=n;j++){
		    	if(rec[i][j]==0)
				    h[i][j]=0;
			    else
				    h[i][j]=h[i-1][j]+1;
			}			    
	//对每一行数据求柱形图最大子矩阵 
		for(int i=1;i<=m;i++){
			stack <int> st;
			int height=0,wide=0;		
			for(int j=1;j<=n+1;j++){
				if(st.empty()||h[i][st.top()]<h[i][j]) 
                    st.push(j);
                else{
        	    while(!st.empty()&&h[i][j]<=h[i][st.top()]) 
				{			        
        		    height=h[i][st.top()];
        		    st.pop();
        		    wide=st.empty() ? (j-1) : j-(st.top()+1) ; 
        		    maxArea=max(maxArea,height*wide);
			    }
			    st.push(j);
			    }
		    }    	
	    }
		cout<<maxArea<<endl;
    }
	return 0;
} 

求柱形图最大子矩阵含注释代码

#include <iostream>
#include <stack>
#include <cstring>
#include <stdio.h>
using namespace std;
int height[100005];
int main(){
    int n;
	scanf("%d",&n);	
	while(n!=0){
		memset(height,0,n+10);//初始化height数组 
	    stack <int> st;//定义一个st栈,用于存放每个矩阵长度单调递增下标索引 
		long long h,w;
		long long maxArea=0;
		int x,j;
		for(j=0;j<n;j++)
		    scanf("%d",&height[j]);
        height[j]=0;//加高度为0的矩形条用于收割 
        for(int i=0;i<=n;i++){
    	    if(st.empty()||height[st.top()]<height[i])//无法确定栈顶矩阵右边界,继续压栈 
                st.push(i);
            else{
        	    while(!st.empty()&&height[i]<=height[st.top()])//确定当前栈顶元素右边界,出栈算面积 
				{			        
        		    h=height[st.top()];
        		    st.pop();
        		    w=st.empty() ? i : i-(st.top()+1) ;//栈为空返回长度i,非空返回长度为当前下标减去栈顶矩阵的位置+1; 
        		    maxArea=max(maxArea,h*w);//比较每一个子矩阵的面积,选出最大的 
			}
			st.push(i);//当前矩阵条进栈 
		}
	}	
	printf("%lld\n",maxArea);
	scanf("%d",&n);
	}
	return 0;      
}

参考博客:
https://blog.csdn.net/qq_42936517/article/details/89501802