学习链接:浅谈用极大化思想解决最大子矩阵问题
模板:
for(i=1;i<=n;i++){//初始化
for(j=1;j<=m;j++){
Right[i][j]=j;
Left[i][j]=j;
height[i][j]=1;
}
}
for(i=1;i<=n;i++){//转移left数组
for(j=2;j<=m;j++){
if(a[i][j]+a[i][j-1]==1)//如果满足条件,即a[i][j]这个点不是阻碍点
Left[i][j]=Left[i][j-1];
}
}
for(i=1;i<=n;i++){//转移right数组
for(j=m-1;j>=1;j--){
if(a[i][j]+a[i][j+1]==1)//如果满足条件
Right[i][j]=Right[i][j+1];
}
}
int ans=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(i>1&&a[i][j]+a[i-1][j]==1){//如果满足条件
height[i][j]=height[i-1][j]+1;
Left[i][j]=max(Left[i-1][j],Left[i][j]);
Right[i][j]=min(Right[i-1][j],Right[i][j]);
}
s=(Right[i][j]-Left[i][j]+1)*height[i][j];//矩阵面积
ans=max(ans,s);//寻找满足条件最大矩阵
}
}
#include<iostream>
#include<cstdio>
using namespace std;
int height[2010][2010],Left[2010][2010],Right[2010][2010];
int a[2010][2010];
int main(void){
int n,m,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
Right[i][j]=j;
Left[i][j]=j;
height[i][j]=1;
}
}
for(i=1;i<=n;i++){
for(j=2;j<=m;j++){
if(a[i][j]+a[i][j-1]==1)
Left[i][j]=Left[i][j-1];
}
}
for(i=1;i<=n;i++){
for(j=m-1;j>=1;j--){
if(a[i][j]+a[i][j+1]==1)
Right[i][j]=Right[i][j+1];
}
}
int max1=0,max2=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(i>1&&a[i][j]+a[i-1][j]==1){
height[i][j]=height[i-1][j]+1;
Left[i][j]=max(Left[i-1][j],Left[i][j]);
Right[i][j]=min(Right[i-1][j],Right[i][j]);
}
int len=Right[i][j]-Left[i][j]+1;
int s=min(len,height[i][j]);
max1=max(max1,s*s);
max2=max(max2,len*height[i][j]);
}
}
cout<<max1<<"\n"<<max2<<"\n";
return 0;
}
#include<iostream>
#include<cstdio>
using namespace std;
int height[2010][2010],Left[2010][2010],Right[2010][2010];
int a[2010][2010];
int main(void){
int n,m,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
Right[i][j]=j;
Left[i][j]=j;
height[i][j]=1;
}
}
for(i=1;i<=n;i++){
for(j=2;j<=m;j++){
if(a[i][j-1]!=0)
Left[i][j]=Left[i][j-1];
}
}
for(i=1;i<=n;i++){
for(j=m-1;j>=1;j--){
if(a[i][j+1]!=0)
Right[i][j]=Right[i][j+1];
}
}
int ans=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(i>1&&a[i-1][j]!=0){
height[i][j]=height[i-1][j]+1;
Left[i][j]=max(Left[i-1][j],Left[i][j]);
Right[i][j]=min(Right[i-1][j],Right[i][j]);
}
if(a[i][j]==0)
continue;
int len=Right[i][j]-Left[i][j]+1;
//cout<<Right[i][j]<<" "<<Left[i][j]<<" len\n";
int s=min(len,height[i][j]);
ans=max(ans,s);
}
}
cout<<ans<<"\n";
return 0;
}
#include<iostream>
#include<cstdio>
using namespace std;
int height[2010][2010],Left[2010][2010],Right[2010][2010];
int a[2010][2010];
int main(void){
int n,m,i,j,t,x,y;
scanf("%d%d",&n,&t);
m=n;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
a[i][j]=1;
}
}
for(i=0;i<t;i++){
scanf("%d%d",&x,&y);
a[x][y]=0;
}
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
Right[i][j]=j;
Left[i][j]=j;
height[i][j]=1;
}
}
for(i=1;i<=n;i++){
for(j=2;j<=m;j++){
if(a[i][j-1]!=0)
Left[i][j]=Left[i][j-1];
}
}
for(i=1;i<=n;i++){
for(j=m-1;j>=1;j--){
if(a[i][j+1]!=0)
Right[i][j]=Right[i][j+1];
}
}
int ans=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(i>1&&a[i-1][j]!=0){
height[i][j]=height[i-1][j]+1;
Left[i][j]=max(Left[i-1][j],Left[i][j]);
Right[i][j]=min(Right[i-1][j],Right[i][j]);
}
if(a[i][j]==0)
continue;
int len=Right[i][j]-Left[i][j]+1;
int s=min(len,height[i][j]);
ans=max(ans,s);
}
}
cout<<ans<<"\n";
return 0;
}
#include<iostream>
#include<cstdio>
using namespace std;
int height[2010][2010],Left[2010][2010],Right[2010][2010];
char a[2010][2010];
int main(void){
int n,m,i,j,t,x,y;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
Right[i][j]=j;
Left[i][j]=j;
height[i][j]=1;
}
}
for(i=1;i<=n;i++){
for(j=2;j<=m;j++){
if(a[i][j-1]=='F')
Left[i][j]=Left[i][j-1];
}
}
for(i=1;i<=n;i++){
for(j=m-1;j>=1;j--){
if(a[i][j+1]=='F')
Right[i][j]=Right[i][j+1];
}
}
int ans=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(i>1&&a[i-1][j]=='F'){
height[i][j]=height[i-1][j]+1;
Left[i][j]=max(Left[i-1][j],Left[i][j]);
Right[i][j]=min(Right[i-1][j],Right[i][j]);
}
if(a[i][j]!='F')
continue;
int len=Right[i][j]-Left[i][j]+1;
//int s=min(len,height[i][j]);
int s=len*height[i][j];
ans=max(ans,s);
}
}
cout<<3*ans<<"\n";
return 0;
}