zoukankan      html  css  js  c++  java
  • luogu SP1805 HISTOGRA

    传送门

    今天是2019.6.4 距离NOIP2019还有157天

    这是一道单调栈的好题

    记得高一下暑假集训的时候肖宇朔学长讲过

    今天突然想到了这道题拿出来再做一遍

    应该是2019年第一道正常难度的题

    题解原先在洛谷上发过一遍了

    这里再发一遍

    题解:只需从左到右维护一个高度递增的栈并且记录每个元素的宽度

    每弹出一个元素的时候用它更新答案

    为什么呢

    因为所有可能成为答案的矩形它的四条边都无法再向四周扩散

    每一个给定的矩形宽度都为一,所以我们不妨从左到右遍历一遍整个矩形图

    假设第一个矩形高是5,那么包含它的可能成为答案的矩形的高度一定是5(显然)

    那么第一个矩形的右面有多少个连续不断的高于第一个矩形矩形就决定了包含它的可能答案(tot)

    如果遇到小于5的一个矩形,就弹出栈中元素,由此合并出可能的答案

    最后枚举答案求出最大值即可

    上代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<string>
    #include<iostream>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #define enter puts("")
    #define space putchar(' ')
    using namespace std;
    typedef long long ll;
    ll read()
    {
        ll op = 1, ans = 0;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = 0;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            ans *= 10;
            ans += ch - '0';
            ch = getchar();
        }
        return op ? ans : -ans;
    }
    void write(ll x)
    {
        if(x < 0)
        {
            x = -x;
            putchar('-');
        }
        if(x >= 10) write(x / 10);
        putchar(x % 10 + '0');
    }
    const int N = 100005;
    struct Drug
    {
        int height;
        int count;
    };
    Drug st[N];
    ll top, h, n, ans, tot, tmp;//tmp存宽度,tot存可能的矩形面积 
    int main()
    {
        while(scanf("%d", &n) != EOF && n)
        {
            top = 0;
            ans = 0;
            for(int i = 1; i <= n; i++)
            {
                h = read(); 
                tmp = 0;
                while(top > 0 && st[top - 1].height >= h)//维护单调栈 
                {
                    tot = st[top - 1].height * (st[top - 1].count + tmp);
                    if (tot > ans) ans = tot;
                    tmp += st[top - 1].count;
                    --top;
                }
                st[top].height = h;
                st[top].count = 1 + tmp;
                ++top;
            }
            tmp = 0;
            while(top > 0)//出栈 
            {
                tot = st[top - 1].height * (st[top - 1].count + tmp);
                ans = max(tot, ans);
                tmp += st[top - 1].count;
                --top;
            }
            write(ans);
            enter;
        }
        return 0;
    }
  • 相关阅读:
    HDU 1031 Design TShirt
    普利姆(Prime)算法
    hdu 2601 An easy problem
    克鲁斯卡尔(Kruskal)算法
    双调欧几里德旅行商问题hdu 2224 The shortest path POJ 2677Tour
    求一个数个各位相加的结果时
    C语言中各种类型的范围
    获取浏览器的scrollTop有几点小疑问
    学习,学习javascript
    各种翻页的效果! FILTER: revealTrans使用说明
  • 原文地址:https://www.cnblogs.com/thx666/p/10976620.html
Copyright © 2011-2022 走看看