1. 程式人生 > >hdu-1506-Largest Rectangle in a Histogram(dp)

hdu-1506-Largest Rectangle in a Histogram(dp)

題目:http://acm.hdu.edu.cn/showproblem.php?pid=1506

 

題意:給出一個n個寬為1的長方形,之後給出第i個長方形的高a[i]。求出由n個長方形組成的圖形所能構成的面積最大的長方形。

 

這道題曾經用單調棧做過,想了解的可以戳這裡(py):https://blog.csdn.net/qq_41157137/article/details/84778190

 

 

基本思路:dp的核心就是用已知一個或多個條件推出未知,題目要求最大的面積,長方形的面積=底X高,由題中所給的要求可知,最大面積的長方形的高一定為所給的高中的一個,即給4個為高4 6 8 9的長方形,最大面積的長方形高一定為其中之一,不會出現1,3,5等等。確定了高後,再來想寬就會好想很多,對於長方形的每個高來說,對應的寬為向左右延伸到第一個小於高的位置。即給4個為高4 6 9 8的長方形,第一個高為4的長方形的寬為區間[1-4],第二個則為[2-4],第三個為[3-3],第四個為[3-4]。在用高乘寬得到面積。這時候看看複雜度O(n^2),暴力肯定涼了。

dp想法:從前往後推每個長方形寬的左邊界,同時如果該長方形左邊有比它高的,可以直接跳到該長方形的左邊界(想清楚:)),同理從後往前推每個長方形寬的右邊界。

 

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <set>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
ll h[maxn];
ll r[maxn];
ll l[maxn];
int main(){
	ll n;
	while (scanf("%lld", &n) != EOF && n){
		for (int i = 1; i <= n; i++){
			scanf("%lld", &h[i]);
			r[i] = i;
			l[i] = i;
		}
		for (int i = 1; i <= n; i++){
			while (l[i] >= 2 && h[l[i] - 1] >= h[i])
				l[i] = l[l[i] - 1];
		}
		ll MAX = -1;
		for (int i = n; i >= 1; i--){
			while (r[i] < n&&h[r[i] + 1] >= h[i])
				r[i] = r[r[i] + 1];
			MAX = max(MAX, h[i] * (r[i] - l[i] + 1));
		}
		printf("%lld\n", MAX);
	}
}