• 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
    ", 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
    ", ans);
        }
    
        return 0;
    }




  • 相关阅读:
    显示AVI的第一桢
    视频采集,存成avi
    视频捕获
    如何将Wav文件做到EXE文件里
    图形整体拉出效果
    3.2 指数型生成函数
    3.1 普通型生成函数
    诡异的楼梯 HDU
    A strange lift HDU
    胜利大逃亡 HDU
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564056.html
Copyright © 2020-2023  润新知