题意
给一个矩阵,一些点有障碍物,求最大子矩阵
做法
悬线法dp
,第一次听说。
步骤
(1)结论:答案一定是一个矩形(废话。。。)
(2)最大矩形一定是:由其中某个点
,先
向上扩展到最大,然后
再分别向左、向右走到最远。
(3)由于(2)的结论对所有点这样操作,一定可以找到最大矩形
具体代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
char a[N][N];
int n,m;
int h[N][N];//每个点往上延申的最大长度
int L[N][N];//在h保证的情况下,每个点往左走最远到哪
int R[N][N];//在h保证的情况下,每个点往右走最远到哪
int ans=0;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
if(a[i][j]=='F')h[i][j]=1;//自己
L[i][j]=R[i][j]=j;//自己
}
}
//在h=1的情况下处理L和R
for(int i=1;i<=n;i++){
//处理L
for(int j=1;j<=m;j++){
if(a[i][j]=='F'&&a[i][j-1]=='F'){
L[i][j]=L[i][j-1];
}
}
//处理R
for(int j=m;j>=1;j--){
if(a[i][j]=='F'&&a[i][j+1]=='F'){
R[i][j]=R[i][j+1];
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]=='F'&&a[i-1][j]=='F'){
h[i][j]=h[i-1][j]+1;//h数组扩展
//L、R向内收缩
L[i][j]=max(L[i][j],L[i-1][j]);
R[i][j]=min(R[i][j],R[i-1][j]);
}
if(a[i][j]=='F'){
ans=max(ans,h[i][j]*(R[i][j]-L[i][j]+1));
}
}
}
cout<<ans*3<<endl;
return 0;
}