zoukankan      html  css  js  c++  java
  • poj 2059 单调栈

    • 题意:求柱状图中最大矩形面积。

    • 单调栈:顾名思义就是栈内元素单调递增的栈。

      每次插入数据来维护这个栈,假设当前须要插入的数据小于栈顶的元素,那就一直弹出栈顶的元素。直到满足当前须要插入的元素大于栈顶元素为止。能够easy求出某个数左边或右边,第一个大于或小于它的数,且复杂度是O(n)

    • 思路:easy先想到一个好的枚举方式:以当前柱状为扩展点,往左边和右边扩展。当遇到一个比当前柱状小的柱状时停止扩展。以当前柱状的高度为矩形的高。向左右扩展的距离之差为矩形的长度,这样对n个柱状进行扫描之后可得最大矩形,复杂度是O(n2),显然超时。

      本题用单调栈来做,维护一个条形图高度的单调栈。

    • 心得:一定要想好了思路,并用伪代码在草稿纸上写一遍再动手写,这道题单调栈实现部分花了大量时间debug,源于思路不清晰。

    简洁的实现:

    • 1.读入当前柱状的高度h。若h大于栈顶元素,则向栈中push(h, i) (i为当前柱状的编号)。若h小于栈顶元素,则弹出栈顶元素,并得到(itopi)toph为栈顶柱状所能扩展得到的最大矩形面积,以此面积来更新全局的最大面积。

      反复上操作,指导栈顶元素小于当前元素。


      2.最后得到一个单调递增的栈,再来用(ntopi)toph来表示栈顶元素所能组成的最大面积。处理并更新完整个栈就可以。

      注:我的代码实现,没实用事实上点做标记,而是一直条形图合并的方法,代码实现复杂了一些

      我的代码:

    #include <set>
    #include <map>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long int LL;
    const int M = 100009,INF = 0x3fffffff;
    
    
    int main(void) {
        //problem: poj2559, address:http://poj.org/problem?

    id=2559 LL n, ans = -1, temp; while (scanf("%lld",&n), n) { ans = -1; pair<LL, LL> key(-99999999 , 1); stack<pair<LL, LL> > s; s.push(key); for (int i = 1; i <= n; i++) { key.second = 1; scanf("%lld", &key.first); int k = 0 ; while (s.top().first >= key.first) { temp = LL(s.top().second + k)*LL( s.top().first); if (temp > ans) ans = temp; key.second += s.top().second; k += s.top().second; s.pop(); } s.push(key); } for (int i = 0; !s.empty();) { temp = LL(s.top().first) * LL(i + s.top().second); if(temp > ans) ans = temp; i += s.top().second; s.pop(); } printf("%lld ", ans); } return 0; }

  • 相关阅读:
    js项目练习第二课
    js项目练习第一课
    进度条
    js基础
    反射
    递归函数与三级菜单
    mybatis 动态SQL
    java 面对对象(抽象 继承 接口 多态)
    java Eclipse debug技巧
    mybatis 调用存储过程
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7394686.html
Copyright © 2011-2022 走看看