題目連結: https://tioj.ck.tp.edu.tw/problems/1470

# 內容

一塊 N*M 單位方格大小的區域中,每一單位都有一個高度。

請你找一塊面積最大的矩形子區域,使得這一個區域中的任一格,其左方 (若在該區域中) 以及上方 (若在該區域中) 的高度皆小於該格的高度。

# 思路

這題有些許神似 (不只些許 ,只不過呢... 這次還需要再多判斷上方的狀況,所以,重新寫了一遍
用 DP 將每點最大的高給記錄下來,再用另一個陣列將同寬記錄下來,之後,就跟那題一樣暴力搜索一下就行了
要記得找到最大的高時,還是要檢查對應其高的兩端點是否在同邊喔!!

# 程式碼

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAXN 100
ll a[MAXN][MAXN] ;
int main(){
	int N ,M ;
	while (cin>>N>>M){
		//input -------------
		for (int i=0 ;i<N ;i++ )
            for (int j=0 ;j<M ;j++ )
				cin>>a[i][j];
		//dp Height----------------
		ll H[MAXN][MAXN] ;
		for (int i=0 ;i<M ;i++ ){
			H[0][i]=1 ;
			for (int j=1 ;j<N ;j++ ){
				if (a[j][i]>a[j-1][i]) H[j][i]=H[j-1][i]+1 ;
				else H[j][i]=1 ;
			}
		}
		//differentiate-----------------------
		ll W[MAXN][MAXN] ;
		for (int i=0 ;i<N ;i++ ){
			W[i][0]=0 ;
			for (int j=1 ;j<M ;j++ )
				if (a[i][j]>a[i][j-1]) W[i][j]=W[i][j-1] ;
				else  W[i][j]=W[i][j-1]+1 ;
		}
		ll ans=0 ;
		for (int i=0 ;i<N ;i++ ){ //column
			for (int l=0 ;l<M ;l++ ){ //left side
				for (int r=l;r<M && W[i][r]==W[i][l] ;r++ ){ //right side
					ll h = 1000;
					for (int k=l ;k<=r ;k++ ) h=min(h,H[i][k]) ;//find height
					for (int k=1 ;k<=h ;k++ ) //check
						if (W[i-k+1][l]!=W[i-k+1][r]){
							h=k-1; break;
						}
					ans=max(ans,h*(r-l+1)) ;
				}
			}
		}
        cout<<ans<<endl;
	}
}
更新於 閱讀次數

用實際行動犒賞爆肝的我😀

Zrn Ye LinePay

LinePay