很像最大子矩阵和
枚举子矩阵在第i行到第j行,sum[k]=∑jia[i][k]
当sum[k]!=j−i+1时,子矩阵不全为1
构建数组b[k]=(sum[k]==j−i+1?1:−inf)
则对b[k]求一次最大子段和,即可得到矩阵高为i~j行时,最长的宽度
#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))
using namespace std;
const int inf=1e9+7;
const int INF = inf;
const int N = 500 + 5;
int a[N][N];
int sum[N],b[N];
int maxLen(int*a,int m){
int sum=0;
int ans=0;
for(int i=0;i<m;++i){
sum+=a[i];
if(sum<0){
sum=0;
}
ans=max(ans,sum);
}
return ans;
}
int slove(int n,int m){
int ans=0;
for(int i=0;i<n;++i){
fill(sum,sum+m,0);
for(int j=i;j<n;++j){
for(int k=0;k<m;++k){
sum[k]+=a[j][k];
b[k]=(sum[k]==(j-i+1)?1:-inf);
}
ans=max(ans,(j-i+1)*maxLen(b,m));
}
}
return ans;
}
int main(){
//freopen("/home/lu/code/r.txt","r",stdin);
//freopen("/home/lu/code/w.txt","w",stdout);
int m,n;
while(~scanf("%d%d",&m,&n)){
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
scanf("%d",&a[i][j]);
}
}
printf("%d\n",slove(n,m));
}
return 0;
}