POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram【堆栈】

问题链接:POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram

问题描述:参见上述链接。

问题分析:解决这个问题,一种是用暴力法(枚举法)来解决,任何一个矩形必然始于第i个直方图,终止于第j块直方图(i<=j),从所有这些面积中找出最大矩形面积即可;另外一种办法是对这n个数只看一遍,就算出最大矩形面积,其计算复杂度为O(n),相比较而言,算法要复杂一些,需要付出一些空间的代价。

程序说明:本程序采用后一种方法实现。基本思想是先找到一个逐步递增的面积,即如果Hi<Hi+1则最大面积是逐步递增的。这个过程中,将这些Hi放入堆栈中,直到不满足Hi<Hi+1为止。这个时候,最大的面积可能是最右边是Hi,由若干块(也可能只有1块)拼成的,从中获得一个最大的面积。出现面积非递增时,则把堆栈中比当前高的直方图弹出,重复上述过程,需要说明的是这不影响高的直方图与其右边连成一片。还有一点就是,所有的直方图的高度Hi>=1,这是一个前提,如果有的直方图高度为0,则这个算法需要另外设计。

参见:CCF201312-3 最大的矩形(解法二)(100分)

AC的C++语言程序如下:

/* POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram */

#include <iostream>
#include <cstdio>
#include <stack>

using namespace std;

const int MAXN = 100000;

long long h[MAXN+1];

int main()
{
    int n, temp;
    long long ans, area;

    while(scanf("%d", &n) != EOF && n) {
        // 输入数据
        for(int i=0; i<n; i++)
            scanf("%lld", &h[i]);
        h[n] = 0;

        // 计算最大矩形面积
        ans = 0;
        stack<int> s;
        for(int i=0; i<=n; i++) {
            if (s.empty() || h[s.top()] < h[i])
                s.push(i);
            else {
                temp = s.top();
                s.pop();            //弹出
                area = h[temp] * (s.empty() ? i : i - s.top() - 1);
                if (area > ans)
                    ans = area;
                --i;
            }
        }

        // 输出结果
        printf("%lld\n", ans);
    }

    return 0;
}

TLE的C++语言程序如下:

/* POJ2559 HDU1506 ZOJ1985 Largest Rectangle in a Histogram */

#include <iostream>
#include <cstdio>

using namespace std;

const int MAXN = 100000;

long long h[MAXN];

int main()
{
    int n;
    long long ans, height, area;

    while(scanf("%d", &n) != EOF && n) {
        // 输入数据
        for(int i=0; i<n; i++)
            scanf("%lld", &h[i]);

        // 计算最大矩形面积:暴力法(枚举法)
        ans = 0;
        for(int i=0; i<n; i++) {
            height = h[i];
            for(int j=i; j<n; j++) {
                if(h[j] < height)
                    height = h[j];
                area = (j - i + 1) * height;
                if(area > ans)
                    ans = area;
            }
        }

        // 输出结果
        printf("%lld\n", ans);
    }

    return 0;
}




转载于:https://www.cnblogs.com/tigerisland/p/7564057.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值