1. 程式人生 > 其它 >HDU 6957 Maximal submatrix(懸線法+單調棧)

HDU 6957 Maximal submatrix(懸線法+單調棧)

分析:類似最大子矩陣問題 判斷條件修改一下就好

up[i][j] 表示點(i,j)最大向上擴充套件的高度 這個可以預處理出來

剩下的就是單調棧的模板題型 求最大矩形面積

對每一行進行單調棧處理 L[i][j] R[i][j]

分別表示點(i,j) 最大向左向右擴充套件的位置

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=2e3+5;
int n,m,ans;
int a[maxn][maxn],L[maxn][maxn],R[maxn][maxn],up[maxn][maxn];
void solve();
stack<int>Q;
int main(){
	int T;
	cin>>T;
	while(T--)solve();
     return 0;
}
void solve(){
	ans=0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
		if(a[i][j]>=a[i-1][j])
		up[i][j]=up[i-1][j]+1;
		else up[i][j]=1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			while(!Q.empty()&&up[i][Q.top()]>up[i][j])R[i][Q.top()]=j-1,Q.pop();
			Q.push(j);
		}
		while(!Q.empty())R[i][Q.top()]=m,Q.pop();
		for(int j=m;j>=1;j--){
			while(!Q.empty()&&up[i][Q.top()]>up[i][j])L[i][Q.top()]=j+1,Q.pop();
			Q.push(j);
		}
		while(!Q.empty())L[i][Q.top()]=1,Q.pop();
		for(int j=1;j<=m;j++)
		ans=max(ans,up[i][j]*(R[i][j]-L[i][j]+1));
	}
	cout<<ans<<endl;
}