最大子矩阵问题--悬线法dp
problem:搜索全为1的最大子矩阵
#include<bits/stdc++.h>
using namespace std;
const int N = 2010;
const int inf = 1000000007;
void in(int &x){
x=0;char c=getchar();
int y=1;
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
x*=y;
}
void o(int x){
if(x<0){x=-x;putchar('-');}
if(x>9)o(x/10);
putchar(x%10+'0');
}
int n,m,i,j,ans,l[N],r[N],h[N],lmax,rmax,a[N][N];
signed main(){
//输入矩阵
in(n);in(m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){;
in(a[i][j]);
}
}
for(i=1;i<=m;i++)l[i]=1,r[i]=m;
for(i=1;i<=n;i++){//枚举每一行
for(j=lmax=1;j<=m;j++) {//搜索左节点
if (a[i][j]){//统计l
h[j]++;//高度增加
if (lmax > l[j])l[j] = lmax;//最进的左
}else h[j] = 0, l[j] = 1, r[j] = m, lmax = j + 1;//无悬线,高度置0,重置,l,r的将最左边的可能点更新化为j——1
}
for (rmax = j = m; j; j--) {
if (a[i][j]){
if (rmax < r[j])r[j] = rmax;//更新右节点
if ((r[j] - l[j] + 1) * h[j] > ans)ans = (r[j] - l[j] + 1) * h[j];//更新面积
}else rmax = j - 1;//更新rmax
}
}
printf("%d",ans);
return 0;
}
P1169 [ZJOI2007]棋盘制作
#include<bits/stdc++.h>
using namespace std;
const int N = 2010;
const int inf = 1000000007;
void in(int &x){
x=0;char c=getchar();
int y=1;
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
x*=y;
}
void o(int x){
if(x<0){x=-x;putchar('-');}
if(x>9)o(x/10);
putchar(x%10+'0');
}
int n,m,i,j,ans1,ans,l[N],r[N],h[N],lmax,rmax,a[N][N];
signed main(){
in(n);in(m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
in(a[i][j]);
}
}
for(int i=1;i<=n;i++)a[i][0]=233,a[i][m+1]=233;
for(int j=1;j<=m;j++)a[0][j]=233,a[n+1][j]=233;
for(i=1;i<=m;i++)l[i]=1,r[i]=m;
for(i=1;i<=n;i++){//枚举每一行
for(j=lmax=1;j<=m;j++) {//搜索左节点
if (a[i][j]!=a[i-1][j]){//统计l
h[j]++;//高度增加
}else h[j]=1,l[j]=1,r[j]=m;
if(a[i][j]!=a[i][j-1]){
if( lmax>l[j])l[j]=lmax;
}else lmax=j,l[j]=j;
}
for (rmax = j = m; j; j--) {
if(a[i][j]!=a[i][j+1]){
if( rmax < r[j])r[j]=rmax;
}else rmax=j,r[j]=j;
if ((r[j] - l[j] + 1) * h[j] > ans)ans = (r[j] - l[j] + 1) * h[j];//更新面积
ans1 = max(ans1,min(r[j]-l[j]+1,h[j]));
}
}
printf("%d
%d
",ans1*ans1,ans);
return 0;
}