hdu-1506-Largest Rectangle in a Histogram(dp)
阿新 • • 發佈:2018-12-28
題目: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); } }