7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0
8 4000
题意 求条形图中最大矩形的面积 输入给你条的个数 每个条的高度hi (以下等于也视为高)
只要知道第i个条左边连续多少个(a)比他高 右边连续多少个(b)比他高 那么以这个条为最大高度的面积就是hi*(a+b+1);
但是直接枚举每一个的话肯定会超时的 超时代码
#include<cstdio> using namespace std; const int N = 100005; typedef long long ll; ll h[N]; int n,wide[N]; int main() { while (scanf ("%d", &n), n) { for (int i = 1; i <= n; ++i) scanf ("%I64d", &h[i]); for (int i = 1; i <= n; ++i) { wide[i] = 1; int k = i; while (k > 1 && h[--k] >= h[i]) ++wide[i]; k = i; while (k < n && h[++k] >= h[i]) ++wide[i]; } ll ans = 0; for (int i = 1; i <= n; ++i) if (h[i]*wide[i] > ans) ans = h[i] * wide[i]; printf ("%I64d\n", ans); } return 0; }
可以发现 当第i-1个比第i个高的时候 比第i-1个高的所有也一定比第i个高
于是可以用到动态规划的思想
令left[i]表示包括i在内比i高的连续序列中最左边一个的编号 right[i]为最右边一个的编号
那么有 当h[left[i]-1]>=h[i]]时 left[i]=left[left[i]-1] 从前往后可以递推出left[i]
同理 当h[right[i]+1]>=h[i]]时 right[i]=right[right[i]+1] 从后往前可递推出righ[i]
最后答案就等于 max((right[i]-left[i]+1)*h[i])了
#include<cstdio> using namespace std; const int N = 100005; typedef long long ll; ll h[N]; int n, left[N], right[N]; int main() { while (scanf ("%d", &n), n) { for (int i = 1; i <= n; ++i) scanf ("%I64d", &h[i]), left[i] = right[i] = i; h[0] = h[n + 1] = -1; for (int i = 1; i <= n; ++i) while (h[left[i] - 1] >= h[i]) left[i] = left[left[i] - 1]; for (int i = n; i >= 1; --i) while (h[right[i] + 1] >= h[i]) right[i] = right[right[i] + 1]; ll ans = 0; for (int i = 1; i <= n; ++i) if (h[i] * (right[i] - left[i] + 1) > ans) ans = h[i] * ll (right[i] - left[i] + 1); printf ("%I64d\n", ans); } return 0; }
HDU 1506 Largest Rectangle in a Histogram(DP),布布扣,bubuko.com
HDU 1506 Largest Rectangle in a Histogram(DP)
原文地址:http://blog.csdn.net/iooden/article/details/38379065