AcWing 3194:最大的矩形 ← 笛卡尔树

【题目来源】
https://www.acwing.com/problem/content/3197/

【题目描述】
在横轴上放了 n 个相邻的矩形,每个矩形的宽度是 1,而第 i(1≤i≤n)个矩形的高度是 hi。
这 n 个矩形构成了一个直方图。
例如,下图中六个矩形的高度就分别是 3,1,6,5,2,3。

请找出能放在给定直方图里面积最大的矩形,它的边要与坐标轴平行。
对于上面给出的例子,最大矩形如下图所示的阴影部分,面积是 10。



【输入格式】
第一行包含一个整数 n,即矩形的数量。
第二行包含 n 个整数 h1,h2,…,hn,相邻的数之间由空格分隔。hi 是第 i 个矩形的高度。

【输出格式】
输出一行,包含一个整数,即给定直方图内的最大矩形的面积。

【输入样例】
6
3 1 6 5 2 3

【输出样例】
10

【数据范围】
1≤n≤1000,
1≤hi≤10000
经实测 hi 在官网的实际范围是 1≤hi≤40000,这与其给出的题面描述不符,属于官网出题人的失误,也因此卡住了一些同学的代码,望大家加以注意。

【算法分析】
● 如何构建笛卡尔树:https://blog.csdn.net/hnjzsyjyj/article/details/138400888

● 笛卡尔树是一种非常特殊的二叉查找树(BST)。每个结点有两个信息
(pri, val),如果只考虑 pri,它是一棵二叉查找树,如果只考虑 val,它是一个小根堆。
一般地,构建笛卡尔树时,我们按第一关键字 pri 排序(很多时候,pri 值即为数组下标)。本题中,pri 值就是数组下标,无需排序,直接按给定的高度建树。

● 如何构建笛卡尔树?(参考于:https://wansuanfa.com/index.php/776)
笛卡尔树的构建步骤如下:(构建前需对 pri 递增排序,或选择数组元素的默认递增下标)
(1)用数组中的第一个元素创建根结点。
(2)遍历数组中剩下的元素,如果新元素比根结点小,让根结点成为新结点的左子结点,然后新结点成为根结点。
(3)如果新结点比根结点大,就从根结点沿着最右边这条路径一种往右走,直到找到比新结点大的结点 node ,也可能没找到。如果找到,就让新结点替换 node 结点的位置,让 node 结点变成新结点的左子结点。如果没找到,就让新结点成为最后查找的那个结点的右子结点。
(4)重复上面步骤(2),(3),直到元素全部遍历完。

● 构建笛卡尔树的关键点解析(参考于:https://wansuanfa.com/index.php/776)
(1)如果新结点比根结点小,根据小根堆(元素的值满足小根堆)的性质,那么新结点一定是根结点的父节点。又因为根结点的下标比新结点小,根据二叉查找树(元素的下标满足二叉查找树)的性质,根结点只能是新结点的左子树。
(2)如果新结点比根结点大,那么新结点只能往右边查找,不能往左边,如果往左边就不满足二叉查找树的性质了。如果比右子结点还大,就继续往右,所以只要比右子结点大就会一直往右。如果比右子结点小,根据小根堆的性质,新结点就会成为这个右子结点的父结点,根据二叉查找树的性质,这个右子结点要成为新结点的左子结点(因为右子结点的下标比新结点小)。

下图为构建笛卡尔树的过程示意图。通过构建过程,易知如何维护笛卡尔树每个结点的两个信息 (pri, val),以及如何保障笛卡尔树具有二叉查找树和堆的双重特性。由图可知,构建方法为以 val 值作为结点,并用其构建小根堆。当需要调整时,以结点插入顺序(或称优先级 pri)为依据,将对应结点置于左子树或右子树,从而保证“如果只考虑 pri,它是一棵二叉查找树”的特性。
简言之,一棵笛卡尔树,val 决定了结点的值,pri 决定了结点的位置。




【算法代码】

#include<bits/stdc++.h>
using namespace std;

const int maxn=1005;
int n;
int top;
int h[maxn],w[maxn];
int ls[maxn],rs[maxn],stk[maxn];

int buildCartesianTree() {
    for(int i=1; i<=n; i++) {
        int t=top;
        while(t && h[stk[t]]>h[i]) t--;
        if(t) rs[stk[t]]=i;
        if(t<top) ls[i]=stk[t+1];
        stk[++t]=i;
        top=t;
    }
    return stk[1];
}

int ans=0;
void dfs(int x) {
    w[x]=1;
    if(ls[x]) {
        dfs(ls[x]);
        w[x]+=w[ls[x]];
    }
    if(rs[x]) {
        dfs(rs[x]);
        w[x]+=w[rs[x]];
    }
    ans=max(ans,w[x]*h[x]);
}

int main() {
    cin>>n;
    for(int i=1; i<=n; i++) cin>>h[i];

    int root=buildCartesianTree();
    dfs(root);
    cout<<ans;
    return 0;
}

/*
in:
6
3 1 6 5 2 3

out:
10
*/





【参考文献】
https://www.cnblogs.com/asdfsag/p/10540265.html
https://wansuanfa.com/index.php/776
https://www.acwing.com/solution/content/98293/
http://www.manongjc.com/detail/12-bqkgltddigmoafg.html
https://blog.csdn.net/hnjzsyjyj/article/details/138400888
https://www.cnblogs.com/silentEAG/p/11555056.html






 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/589970.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

类和对象【四】运算符重载

文章目录 运算符重载的概念运算符重载&#xff08;函数&#xff09;返回值类型&#xff1a;任意类型函数名&#xff1a;operator已有操作符 运算符重载&#xff08;函数&#xff09;的特点和注意点3个比较特殊的运算符重载赋值运算符&#xff08;&#xff09;重载返回值类型和返…

Linux CentOS7部署ASP.NET Core应用程序,并配置Nginx反向代理服务器和Supervisor守护服务

前言&#xff1a; 本篇文章主要讲解的是如何在Linux CentOS7操作系统搭建.NET Core运行环境并发布ASP.NET Core应用程序&#xff0c;以及配置Nginx反向代理服务器。因为公司的项目一直都是托管在Window服务器IIS上&#xff0c;对于Linux服务器上托管.NET Core项目十分好奇。因为…

简单学生信息管理系统

简单&#xff0c;单表&#xff1b; https://download.csdn.net/download/bcbobo21cn/89251742

【QT学习】12.UDP协议,广播,组播

一。Udp详细解释 UDP&#xff08;User Datagram Protocol&#xff09;是一种无连接的传输层协议&#xff0c;它提供了一种简单的、不可靠的数据传输服务。与TCP相比&#xff0c;UDP不提供可靠性、流量控制、拥塞控制和错误恢复等功能&#xff0c;但由于其简单性和低开销&#x…

Java | Leetcode Java题解之第64题最小路径和

题目&#xff1a; 题解&#xff1a; class Solution {public int minPathSum(int[][] grid) {if (grid null || grid.length 0 || grid[0].length 0) {return 0;}int rows grid.length, columns grid[0].length;int[][] dp new int[rows][columns];dp[0][0] grid[0][0]…

《罪与罚》读后感

陀思妥耶夫斯基和列夫托尔斯泰是公认的俄国文学黄金时代的两座高峰&#xff0c;分别代表着俄国文学的“深度”和“广度”。列夫托尔斯泰的鸿篇巨著《复活》《安娜卡列尼娜》等等都已经拜读过&#xff0c;但陀思妥耶夫斯基的作品却一本也没有看过&#xff0c;实在是有点遗憾。这…

LabVIEW换智能仿真三相电能表研制

LabVIEW换智能仿真三相电能表研制 在当前电力工业飞速发展的背景下&#xff0c;确保电能计量的准确性与公正性变得尤为重要。本文提出了一种基于LabVIEW和单片机技术&#xff0c;具有灵活状态切换功能的智能仿真三相电能表&#xff0c;旨在通过技术创新提高电能计量人员的培训…

Flutter笔记:谈Material状态属性-为什么FlatButton等旧版按钮就废弃了

Flutter笔记 谈Material状态属性-为什么FlatButton等旧版按钮就废弃了 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this artic…

MySQL-逻辑架构

1、MySQL服务器处理客户端请求 MySQL是典型的C/S架构&#xff0c;服务端程序使用 mysqld。实现效果&#xff1a;客户端进程像服务端发送&#xff08;SQL语句&#xff09;&#xff0c;服务器进程处理后再像客户端进程发送 处理结果。 2、connectors 指不同语言中与SQL的交互…

Vue3+ts(day05:ref、props、生命周期、hook)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】&#xff0c;记录一下学习笔记&#xff0c;用于自己复盘&#xff0c;有需要学…

OpenMLDB v0.9.0 发布:SQL 能力大升级覆盖特征上线全流程

发布日期 25 April 2024 Release note https://github.com/4paradigm/OpenMLDB/releases/tag/v0.9.0 亮点特性 增加最新版 SQLAlchemy 2 的支持&#xff0c;无缝集成 Pandas 和 Numpy 等常用 Python 框架。支持更多数据后端&#xff0c;融合 TiDB 的分布式文件存储能力以及…

【Redis】Redis安装、配置、卸载使用可视化工具连接Redis

文章目录 1.前置条件2.安装Redis2.1下载Redis安装包并解压2.2在redis目录下执行make命令2.3修改Redis配置文件2.4启动Redis服务2.5连接redis服务 3.Redis卸载4.使用可视化工具连接Redis 1.前置条件 Linux操作系统需要要是64位.如果不清楚自己Linux上是多少位的,可以使用以下命…

详解 Go 程序的启动流程,你知道 g0,m0 是什么吗?

自古应用程序均从 Hello World 开始&#xff0c;你我所写的 Go 语言亦然&#xff1a; import "fmt"func main() {fmt.Println("hello world.") }这段程序的输出结果为 hello world.&#xff0c;就是这么的简单又直接。但这时候又不禁思考了起来&#xff0…

vue3 ——笔记 (表单输入,监听器)

表单输入 在Vue 3中&#xff0c;v-model指令的用法稍有不同于Vue 2。在Vue 3中&#xff0c;v-model指令实际上是一个语法糖&#xff0c;它会自动将value属性和input事件绑定到组件或元素上&#xff0c;以实现双向数据绑定。 在自定义组件中使用v-model时&#xff0c;需要在组…

SQL注入漏洞--报错/union/布尔盲注/时间盲注

之前介绍了数据库的基本操作&#xff0c;今天这篇文章就来实操SQL注入。 阅读本文前可以先看一下基本操作&#xff0c;有助于更好理解本文。。。 https://blog.csdn.net/weixin_60885144/article/details/138356410?spm1001.2014.3001.5502 what SQL---结构化查询语言---S…

Codeforces Round 943 (Div. 3) (A-G1) C++题解

目录 比赛链接 : A. Maximize? B. Prefiquence C. Assembly via Remainders D. Permutation Game E. Cells Arrangement F. Equal XOR Segments G1. Division LCP (easy version) G2. Division LCP (hard version) 比赛链接 : Dashboard - Codeforces Round 943 (…

用vim或gvim编辑程序

vim其实不难使用&#xff0c;学习一下就好了。简单功能很快学会。它有三种模式&#xff1a;命令模式&#xff0c;编辑模式&#xff0c;视模式。打开时在命令模式。在命令模式下按 i 进入编辑模式&#xff0c;在编辑模式下按<Esc>键退出编辑模式。在命令模式按 :wq 保存文…

Python-100-Days: Day08 Object-oriented programming(OOP) basics

OOP definition 把一组数据结构和处理它们的方法组成对象&#xff08;object&#xff09;&#xff0c;把相同行为的对象归纳为类&#xff08;class&#xff09;&#xff0c;通过类的封装&#xff08;encapsulation&#xff09;隐藏内部细节&#xff0c;通过继承&#xff08;in…

C/C++开发环境配置

配置C/C开发环境 1.下载和配置MinGW-w64 编译器套件 下载地址&#xff1a;https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/ 下载后解压并放至你容易管理的路径下&#xff08;我是将其放在了D盘的一个software的文件中管理&#xff09; 2.…

古典密码学简介

目录 C. D. Shannon: 一、置换密码 二、单表代替密码 ① 加法密码 ② 乘法密码 ③密钥词组代替密码 三、多表代替密码 代数密码 四、古典密码的穷举分析 1、单表代替密码分析 五、古典密码的统计分析 1、密钥词组单表代替密码的统计分析 2、英语的统计规…