题面1:

题面2:

两道题除了数据范围不同,没有任何差异,两道题都可以o(n)(单调栈),o(nlog(n))(我自己的做法)解决。

解题思路1:(单调栈)

  1. 对于每个点找到右边第一个比它小的位置con1,并且找到左边第一个比它小的位置con2。
  2. 对于每个点更新答案为ans = max(ans, (con2-con1-1)*value[i])。
  3. 1的做法是两次裸的单调栈,时间复杂度为o(n)。

代码1:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//在新疆大学OJ提交需要将此处三个数组改为500010,否则会运行超时
ll a[50010];
int l[50010],r[50010];
int main(){ios::sync_with_stdio(false);int n;cin >> n;ll ans = 0;for(int i = 1;i <= n; ++i){cin >> a[i];}a[0] = a[n+1] = -1;stack<int> s;s.push(1);for(int i = 2;i <= n+1; ++i){if(a[i] < a[s.top()]){while(s.size() and a[i] < a[s.top()]){r[s.top()] = i;s.pop();}}s.push(i);}while(s.size()) s.pop();s.push(n);for(int i = n-1;i >= 0; --i){if(a[i] < a[s.top()]){while(s.size() and a[i] < a[s.top()]){l[s.top()] = i;s.pop();}}s.push(i);}for(int i = 1;i <= n; ++i){ans = max(ans, (a[i]*(r[i]-l[i]-1)));}cout << ans << endl;return 0;
}

解题思路2:(拼凑段)

  1. 这是我自己瞎搞的写法,不知道算什么方法,不过大家可以看一看思路,可能什么时候就能用到了。
  2. 首先,记下输入的数字的位置,然后对这个结构体按数字从打到小排序。
  3. 遍历这个结构体数组(这时数字是从大到下的),段(一个结构体,有l,r,used三个成员变量,l指这个段的左端位置,r指这个段的右端位置)

    a. 若这个数字的原位置的左右边两个数字都已形成段,则将这两段拼成一段,具体做法是将左边段的r延长至右端,当前数字为这一段的最小值,更新ans。
    b. 若这个数字的原位置的左边形成段,右边没有形成段,则把这个数字加入到左边的段,当前数字为这一段的最小值,更新ans。
    c. 若这个数字的原位置的右边形成段,左边没有形成段,则把这个数字加入到右边的段,当前位置为这一段的最小值,更新ans。
    d. 若这个数字的原位置的左边和右边都没有形成段,则把这个数字加入到一个新的段,新的段的l和r都等于这个数字的原先位置,更新ans。

  4. 可能会想到查找左边位置所处的段和右边所处的段需要o(n)处理起来会变成o(n^2),这时候我们加一个索引数组index,index[i]表示位置为i的数字所处的段。

  5. 可能还会想到更新index需要花费o(n),处理起来会变成o(n^2),但是仔细想想我们会发现不需要更新这个段所有的index,只用更新index[l]和index[r],因为中间的在后面将不会用到。
  6. 这样算下来排序的时间复杂度是o(nlogn),处理的时间是o(n),总时间复杂度就是o(nlogn)。
  7. 可能还有人问为什么正确?排序之后先插入大的,后插入小的,会发现当前插入的这个点一定是这个点的最优情况。

代码2:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//在新疆大学OJ提交需要将此处的50010全部改为500010 //输入的数组,val为这个点的数字,idx表示原下标。
struct node{ll val;int idx;
}a[50010];
//段,l表示左端,r表示右端 ,k表示段的个数。
struct segment{int l;int r;
}seg[50010];
int k = 1;
//index[i]表示第i个位置数字所处的段。
int index[50010];int n;
bool cmp(node x,node y){return x.val > y.val;
}int main(){ios::sync_with_stdio(false);int n;cin >> n;ll ans = 0;for(int i = 1;i <= n; ++i){cin >> a[i].val;a[i].idx = i;ans = max(ans , a[i].val);}sort(a+1, a+1+n, cmp);for(int i = 1;i <= n; ++i){int idxl = index[a[i].idx-1];int idxr = index[a[i].idx+1];if(idxl != 0 and idxr != 0){    //左右边都形成一段。 seg[idxl].r = seg[idxr].r;index[seg[idxr].r] = idxl;ans = max(ans, a[i].val*(seg[idxl].r-seg[idxl].l+1));}else if(idxl != 0 and idxr == 0){  //左边形成段,右边未形成。 seg[idxl].r++;index[a[i].idx] = idxl;ans = max(ans, a[i].val*(seg[idxl].r-seg[idxl].l+1));}else if(idxl == 0 and idxr != 0){  //右边形成段,左边未形成。 seg[idxr].l--;index[a[i].idx] = idxr;ans = max(ans, a[i].val*(seg[idxr].r-seg[idxr].l+1));}else if(idxl == 0 and idxr == 0){  //左右边均未形成段。 seg[k].l = a[i].idx;seg[k].r = a[i].idx;index[a[i].idx] = k; k++;}}cout << ans << endl;return 0;
}

51nod 1102 面积最大的矩形 新疆大学OJ 1387: B.HUAWEI's billboard 【单调栈】+【拼凑段】(o(n) 或 o(nlog(n))相关推荐

  1. 51Nod 1102 面积最大的矩形 +1272 最大距离 单调栈

    51Nod 1102 面积最大的矩形 记笔记记笔记:对于区间最值与区间长度/和等的问题,用单调栈来维护区间端点. 这里来补一补单调栈和单调队列的基础知识: 单调栈:                   ...

  2. leetcode84- 柱状图中最大的矩形(三种思路:暴力,单调栈+哨兵(详解),分治)

    leetcode84- 柱状图中最大的矩形(三种思路:暴力,单调栈+哨兵(详解),分治) 介绍 题目 解题思路 解法一:暴力向两边搜索 解法二:单调栈 画图演示 宽度计算: 解法三:单调栈+哨兵 解法 ...

  3. SUST OJ 1675: Fehead的项目(单调栈)

    1675: Fehead的项目 时间限制: 1 Sec  内存限制: 128 MB 提交: 41  解决: 27 [提交][状态][讨论版] 题目描述 Fehead俱乐部接手了一个项目,为了统计数据, ...

  4. 51nod 1158 全是1的最大子矩阵(单调栈 ,o(n*m))

    前置问题:51nod 1102 面积最大的矩形 附上链接: 51nod 1102 面积最大的矩形 这题的题解博客 需要了解的知识:单调栈,在前置问题中已经讲解. 解题思路 对每行求左边连续1的个数,得 ...

  5. 的input最大长度_LeetCode 84 | 单调栈解决最大矩形问题

    今天是LeetCode专题第52篇文章,我们一起来看LeetCode第84题,Largest Rectangle in Histogram(最大矩形面积). 这道题的官方难度是Hard,点赞3581, ...

  6. 如何用课件制作工具演示面积一定的矩形

    作为数学老师必备的课件制作工具,几何画板不仅可以画固定形状的几何图形,还可以构造变换的几何图形.比如可以用它来演示面积一定的矩形,那就说明矩形的长和宽是可以变化的,可以看到矩形的形状是变化的.下面就一 ...

  7. 计算直方图中面积最大的矩形

    CSDN编程挑战里的题目 给定直方图,每一小块的height由N个非负整数所确定,每一小块的width都为1,请找 出直方图中面积最大的矩形. 如下图所示,直方图中每一块的宽度都是1,每一块给定的高度 ...

  8. 【每日一题】最大正方形面积——进阶,矩形面积

    2020/05/08 每日一题 221 最大正方形面积 是一道做过的题目出现在了每日一题,今后的每日一题我尽量把相关的题目都写一遍. 这道题目的思路并不是看到01矩阵就采用暴力的bfs方法,而是可以采 ...

  9. POJ 2559 题解 最大矩形面积 单调栈

    [题目描述]: 地面上从左到右并排紧挨着摆放多个矩形,已知这此矩形的底边宽度都为1,高度不完全相等.求在这些矩形包括的范围内能得到的面积最大的矩形,打印出该面积.所求矩形可以横跨多个矩形,但不能超出原 ...

最新文章

  1. 2.2 物理层传输介质
  2. 数据集神经网络共同进步
  3. 射线法 java_射线法(1190 - Sleepwalking )
  4. java web从入门到精通视频_JavaWeb从入门到精通(视频实战版)
  5. 2020 年 Service Mesh 技术展望
  6. gym 102875 H. Happy Morse Code
  7. TomCat使用以及端口号被占用的处理方法
  8. opencv计算物体姿态旋转_物体的三维识别与6D位姿估计:PPF系列论文介绍(五)...
  9. 20个软件开发常用设计文档大全下载
  10. 计算机考研调剂规则,21考研调剂规则大变化,这类学生不能调剂!
  11. 用8张图理解Java
  12. N76E003的学习之路(一)
  13. Python的继承与多继承
  14. 深入理解和使用nginx
  15. 计算机操作系统第四版课后习题答案(完整版)
  16. AD快捷键备份20210202
  17. EDA技术及应用实验2 h_adder程序
  18. 联想g510升级换什么cpu好_联想G510笔记本完全拆机指南(图解)
  19. php1蛋白质带电情况,拿到一个蛋白以后,首先需要对蛋白进行全面的了解,所谓知彼知己方能百战不殆:...
  20. 网络信息安全期末复习要点

热门文章

  1. Java黑皮书课后题第7章:*7.22(计算一个字符串中大写字母的数目)编写程序,从命令行输入一个字符串,然后显示字符串中大写字母的数目
  2. whiel oracle,Oracle中的for和while循环
  3. java理念_java温故而知新(9)OOP(面向对象编程)理念
  4. 15个Google面试题以及答案~~~~你会几个?
  5. 任意长度的高精度大整数加法
  6. mongoose 验证
  7. P4198 楼房重建
  8. $.ajax()方法详解(网上引用)
  9. halcon11用于C++的HTuple.h头文件,纯手添中文翻译!
  10. HNCU 1741: 算法3-2:行编辑程序