单调栈裸题

如果矩形高度从左到右是依次递增,那我们枚举每个矩形高度,宽度拉到最优,计算最大面积即可

当有某个矩形比前一个矩形要矮的时候,这块面积的高度就不能大于他本身,所以之前的所有高于他的矩形多出来的部分都没用了,不会再计算第二次。

因此我们只需要用单调栈维护矩形高度即可,当有高度较低的矩形进栈时,先将之前比他高的每个矩形弹出,宽度累加,更新答案。然后我们要进栈的矩形的宽度也要变成之前累加的宽度+1,因为要保留有用部分。。

有个小技巧:为了方便程序,在末尾加一个高度为0的矩形

  1. #include <bits/stdc++.h>
  2. #define INF 0x3f3f3f3f
  3. using namespace std;
  4. typedef long long ll;
  5. inline int lowbit(int x){ return x & (-x); }
  6. inline int read(){
  7. int X = 0, w = 0; char ch = 0;
  8. while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
  9. while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
  10. return w ? -X : X;
  11. }
  12. inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
  13. inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
  14. template<typename T>
  15. inline T max(T x, T y, T z){ return max(max(x, y), z); }
  16. template<typename T>
  17. inline T min(T x, T y, T z){ return min(min(x, y), z); }
  18. template<typename A, typename B, typename C>
  19. inline A fpow(A x, B p, C yql){
  20. A ans = 1;
  21. for(; p; p >>= 1, x = 1LL * x * x % yql)if(p & 1)ans = 1LL * x * ans % yql;
  22. return ans;
  23. }
  24. ll h[100005], s[100005], w[100005], tot;
  25. int main(){
  26. int n;
  27. while(cin >> n && n){
  28. memset(h, 0, sizeof h);
  29. memset(s, 0, sizeof s);
  30. memset(w, 0, sizeof w);
  31. ll ans = 0; w[n + 1] = 0; tot = 0;
  32. for(int i = 1; i <= n; i ++) cin >> h[i];
  33. for(int i = 1; i <= n + 1; i ++){
  34. if(s[tot] > h[i]){
  35. ll width = 0;
  36. while(tot > 0 && s[tot] > h[i]){
  37. width += w[tot];
  38. ans = max(ans, (ll)width * s[tot]);
  39. tot --;
  40. }
  41. s[++tot] = h[i], w[tot] = width + 1;
  42. }
  43. else{
  44. s[++tot] = h[i], w[tot] = 1;
  45. }
  46. }
  47. printf("%lld\n", ans);
  48. }
  49. return 0;
  50. }

再来个笛卡尔树做法

  1. #include <bits/stdc++.h>
  2. #define INF 0x3f3f3f3f
  3. #define full(a, b) memset(a, b, sizeof a)
  4. #define __fastIn ios::sync_with_stdio(false), cin.tie(0)
  5. #define pb push_back
  6. using namespace std;
  7. typedef long long LL;
  8. inline int lowbit(int x){ return x & (-x); }
  9. inline int read(){
  10. int ret = 0, w = 0; char ch = 0;
  11. while(!isdigit(ch)){
  12. w |= ch == '-', ch = getchar();
  13. }
  14. while(isdigit(ch)){
  15. ret = (ret << 3) + (ret << 1) + (ch ^ 48);
  16. ch = getchar();
  17. }
  18. return w ? -ret : ret;
  19. }
  20. template <typename A>
  21. inline A __lcm(A a, A b){ return a / __gcd(a, b) * b; }
  22. template <typename A, typename B, typename C>
  23. inline A fpow(A x, B p, C lyd){
  24. A ans = 1;
  25. for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
  26. return ans;
  27. }
  28. const int N = 200005;
  29. LL h[N], ans;
  30. int n;
  31. struct Node{
  32. int i, size;
  33. LL val;
  34. Node *fa, *lf, *rf;
  35. Node(){}
  36. Node(int i, LL val): i(i), val(val){
  37. fa = lf = rf = nullptr;
  38. size = 0;
  39. }
  40. }*root;
  41. Node *buildTree(){
  42. stack<Node*> st;
  43. Node *last = nullptr;
  44. for(int i = 1; i <= n; i ++){
  45. Node *cur = new Node(i, h[i]);
  46. while(!st.empty()){
  47. if(st.top()->val < cur->val){
  48. Node *up = st.top();
  49. if(up->rf) cur->lf = up->rf, up->rf->fa = cur;
  50. up->rf = cur, cur->fa = up;
  51. break;
  52. }
  53. last = st.top(); st.pop();
  54. }
  55. if(st.empty() && last) last->fa = cur, cur->lf = last;
  56. st.push(cur);
  57. }
  58. Node *root = nullptr;
  59. while(!st.empty()) root = st.top(), st.pop();
  60. return root;
  61. }
  62. void dfs(Node *rt){
  63. if(rt == nullptr) return;
  64. rt->size = 1;
  65. dfs(rt->lf), dfs(rt->rf);
  66. if(rt->lf) rt->size += rt->lf->size;
  67. if(rt->rf) rt->size += rt->rf->size;
  68. ans = max(ans, 1LL * rt->size * rt->val);
  69. }
  70. int main(){
  71. while(~scanf("%d", &n) && n){
  72. for(int i = 1; i <= n; i ++) scanf("%lld", &h[i]);
  73. root = buildTree();
  74. ans = 0, dfs(root);
  75. printf("%lld\n", ans);
  76. }
  77. return 0;
  78. }

HDU1506 Largest Rectangle in a Histogram(算竞进阶习题)的更多相关文章

  1. hdu---1506(Largest Rectangle in a Histogram/dp最大子矩阵)

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  2. hdu1506——Largest Rectangle in a Histogram

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  3. hdu1506 Largest Rectangle in a Histogram

    Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a commo ...

  4. HDU1506 Largest Rectangle in a Histogram (动规)

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  5. NYOJ-258/POJ-2559/HDU-1506 Largest Rectangle in a Histogram,最大长方形,dp或者单调队列!

                                         Largest Rectangle in a Histogram 这么经典的题硬是等今天碰到了原题现场懵逼两小时才会去补题.. ...

  6. 【题解】hdu1506 Largest Rectangle in a Histogram

    目录 题目 思路 \(Code\) 题目 Largest Rectangle in a Histogram 思路 单调栈. 不知道怎么描述所以用样例讲一下. 7 2 1 4 5 1 3 3 最大矩形的 ...

  7. HDU-1506 Largest Rectangle in a Histogram【单调栈】

    Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...

  8. HDU1506 ( Largest Rectangle in a Histogram ) [dp]

    近期情绪太不稳定了.可能是由于在找实习这个过程碰壁了吧.第一次面试就跪了,可能是我面的是一个新公司,制度不完好,我感觉整个面试过程全然不沾编程,我面试的还是软件开发-后来我同学面试的时候.说是有一道数 ...

  9. 【单调栈】hdu1506 Largest Rectangle in a Histogram

    单调栈的介绍及一些基本性质 http://blog.csdn.net/liujian20150808/article/details/50752861 依次把矩形塞进单调栈,保持其单增,矩形中的元素是 ...

随机推荐

  1. Linux 命令(二)

    man help:线上查询及帮助命令 命令  --help:简单帮助 help  cd:查看一些Linux命令行的一些内置命令 文件和目操作命令(19个) ls  cd  cp  find  mkdi ...

  2. Python-待

    内置函数总结 https://www.cnblogs.com/jason-lv/p/8243141.html https://www.cnblogs.com/pyyu/p/6702896.html 数 ...

  3. hdu3790 dijkstra+堆优化

    题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=3790 分析:dijkstra没有优化的话,复杂度是n*n,优化后的复杂度是m*logm,n是顶点数,m ...

  4. #Leetcode# 985. Sum of Even Numbers After Queries

    https://leetcode.com/problems/sum-of-even-numbers-after-queries/ We have an array A of integers, and ...

  5. 分布式ID生成系统 UUID与雪花(snowflake)算法

    Leaf——美团点评分布式ID生成系统 -https://tech.meituan.com/MT_Leaf.html 网游服务器中的GUID(唯一标识码)实现-基于snowflake算法-云栖社区-阿 ...

  6. linux如何查看所有的用户(user)、用户组(group)、密码(password/passwd)

    linux如何查看所有的用户和组信息_百度经验https://jingyan.baidu.com/article/a681b0de159b093b184346a7.html linux添加用户.用户组 ...

  7. C#设计模式之4:装饰者模式

    装饰者模式 背景是有一家星巴兹咖啡店,由于客源充足,所以决定重新设计他们的收费系统,以前的收费系统中只定义了一个表示饮料的Beverage的基类,它里面定义了一个Cost的方法用来计算饮料的花费,但是 ...

  8. php分割中文字符串为数组的简单例子

    近日在做东西时,遇到要把中文字符进行逐字分割,试了很多方法,都不行,后来发现了一个超简单的方法: 分割字符串很简单,主要是用到函数preg_match_all.当处理含有中文的字符串时,可以用如下的方 ...

  9. Java线程的5种状态及切换(透彻讲解)-京东面试

    一.Thread的几个重要方法: 我们先了解一下Thread的几个重要方法. a.start()方法,开始执行该线程:b.stop()方法,强制结束该线程执行:c.join方法,等待该线程结束.d.s ...

  10. @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

    @EnableAutoConfiguration 作用:Spring Boot会自动根据你jar包的依赖来自动配置项目. 例如当你项目下面有HSQLDB的依赖时,Spring Boot会创建默认的内存 ...