#include<bits/stdc++.h> //以列宽为突破点
using namespace std;
const int N=5e3;
char str[N+100];
int s[N+100][N+100];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",str);
for(int j=1;j<=m;j++)
{
if(str[j-1]=='1') s[i+1][j]=s[i+1][j-1]+1;
}
}
int sub[N+100],ans=0;
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
sub[i]=s[i][j];
}
sort(sub+1,sub+n+1);
for(int i=1;i<=n;i++)
{
ans=max(ans,(n-i+1)*sub[i]);
}
}
printf("%d\n",ans);
return 0;
}
#include<bits/stdc++.h>//(想到了解法但超时)数组a~,i代表长方形的起点,j代表行宽,a[i][j]代表列长.
using namespace std; //也算压缩到行去处理了
const int N=5000;
char str[N+100];
int a[N+100][N+100];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int ans=0;
for(int i=0;i<n;i++)
{
scanf("%s",str);
for(int j=0;j<m;j++)
{
if(str[j]-'0')
{
int cn=0;
for(int k=j;k<m;k++) //这一层优化不了了
{
if(str[k]-'0') {a[j][++cn]++;ans=max(ans,a[j][cn]*cn);} //行宽固定每组合要求的宽都加上去。(行能调换嘛)
else {break;}
}
}
}
}
// for(int i=0;i<m;i++)
// {
// for(int j=1;j<=m;j++)
// printf("%d ",a[i][j]);
// printf("\n");
// }
printf("%d\n",ans);
return 0;
}
Maximum Submatrix 2