题目给一个01矩阵,求最大的1子矩阵。
先用dp预处理出每一行的每一列的1能向上按连续的1延伸多少,然后枚举每一行作为子矩阵的底,那样对于每一行的答案就是POJ2559这个经典问题了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define MAXN 2222 6 int stack[MAXN],top,l[MAXN],r[MAXN]; 7 int calc(int *a,int n){ 8 a[++n]=-1; top=0; 9 for(int i=1; i<=n; ++i){ 10 l[i]=r[i]=i; 11 while(top && a[stack[top]]>a[i]){ 12 r[stack[top]]=i-1; 13 l[i]=l[stack[top]]; 14 --top; 15 } 16 if(top && a[stack[top]]==a[i]) l[i]=l[stack[top]]; 17 stack[++top]=i; 18 } 19 int res=0; 20 for(int i=1; i<n; ++i){ 21 res=max(res,a[i]*(r[i]-l[i]+1)); 22 } 23 return res; 24 } 25 int d[MAXN][MAXN]; 26 int main(){ 27 int n,m; 28 while(~scanf("%d%d",&n,&m)){ 29 for(int i=1; i<=n; ++i){ 30 for(int j=1; j<=m; ++j) scanf("%d",&d[i][j]); 31 } 32 for(int i=1; i<=n; ++i){ 33 for(int j=1; j<=m; ++j){ 34 if(d[i][j]) d[i][j]=d[i-1][j]+1; 35 } 36 } 37 int res=0; 38 for(int i=1; i<=n; ++i){ 39 res=max(res,calc(&d[i][0],m)); 40 } 41 printf("%d ",res); 42 } 43 return 0; 44 }