当前位置: 首页 > news >正文

刷题记录:牛客NC50965Largest Rectangle in a Histogram

传送门:牛客

在这里插入图片描述

输入:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
输出:
8
4000

个人感觉这道题的思维含量还是很高的,感觉真正的理解了这道题的话那么对于普通的单调栈以及单调队列之类的题目应该是没有什么问题了的

针对这道题的理解方面的难度,我先贴出主代码

struct Juxing{
	ll num,pos;
};
stack<Juxing>q;
int main() {
	ll n;
	while(cin>>n) {
		if(n==0) break;
		ll num;ll maxx=0;
		for(int i=1;i<=n;i++) {
			num=read();int pos=i;
			while(!q.empty()&&num<=q.top().num) {
				pos=q.top().pos;
				maxx=max(q.top().num*(i-q.top().pos),maxx);
				q.pop();
			}	
			q.push({num,pos});
		}
		while(!q.empty()) {
			maxx=max(maxx,q.top().num*(n-q.top().pos+1));
			q.pop();
		}
		printf("%lld\n",maxx);
	}
	return 0;
}

目前不明白不要紧,等会会一一解释

首先对于我们的题目,我们需要求出面积的最大值,抛开这个题目,我们先来想一想假设我们有一个单调增的矩形序列,比如A<B<C,那么此时我们的答案应该怎么得到呢,手模一下我们会发现可以从右往左依次移动,每一次的移动后的答案都是由最左边的值来决定的,比如我们现在指针指向了B位置,显然对于A来说,他是小于B的,不贡献我们的答案,对于C来说,最多也只能贡献B.此时我们就会发现如果这个序列是一个单调增的序列,那么此时的答案会非常容易的求出,

但是题目给我们的矩形显然不是单调增的,我们该怎么维护这个序列呢

我们假设当前有一串单调增的序列

A,B,C…K

此时我们K的下一个遇到了M

我们假设如果M>=k,那么显然可以和之前一起构成一个单调序列

如果M<K,那么我们此时在A到K的这段区间中找到一个位置D,使得D位置的值比我们的M要大(当然

可能找不到,等会另说)

当我们找到这个D位置我们会发现num[D]>num[C],num[K]>num[M].显然此时我们的D到K的位置的

值都是比我们的C与M要大的,也就是说这个区间要是左右扩大的话最大也只能贡献出D的答案,因此

此时我们不妨就直接算出这段区间内的答案(反正最后取得是每一段区间贡献的答案的最大值),然后

将其踢出我们的序列,因为此时这个区间相当于是没有用了的,对外来说直接采用M即可(因为M是相

对最低点,如果加入了M,贡献不会超过M),并且此时为了后序计算的方便,此时我们可以直接将M移动

到D的位置来代替D,因为之后我们从后往前算长度时,D到K的区间都是当M的贡献来计算的,注意此

时我们只算了区间内的贡献,可能有人会疑问为什么不计算K之前的所有贡献呢,因为C肯定是比D小

的,之后D到K区间都按照M来算之后,整个序列就将会是一个单调序列,此时我们的之前的贡献也会一

并算出

总结一下,大概就是找出中间大,两端小的区间(并且这个区间是一个单调区间,因为单调区间比较好求),然后求出这个区间的贡献,并将整个区间当做较小的那个数使用

经过上述的维护之后,我们就去掉了原本不是单调的部分已经得到了一个单调序列,接着直接用我们

讲的方法直接求出这个单调序列的贡献即可

因为这道题比较麻烦,可能讲的并不是很清楚,有些细节也不好讲解,请感性的了解之后结合代码进行食用

代码部分:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string.h>
#include <stack>
#include <deque>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
	ll x=0,w=1;char ch=getchar();
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
	return x*w;
}
#define maxn 1000000
#define ll_maxn 0x3f3f3f3f3f3f3f3f
const double eps=1e-8;
struct Juxing{
	ll num,pos;
};
stack<Juxing>q;
int main() {
	ll n;
	while(cin>>n) {
		if(n==0) break;
		ll num;ll maxx=0;
		for(int i=1;i<=n;i++) {
			num=read();int pos=i;
			while(!q.empty()&&num<=q.top().num) {
				pos=q.top().pos;
				maxx=max(q.top().num*(i-q.top().pos),maxx);
				q.pop();
			}	
			q.push({num,pos});
		}
		while(!q.empty()) {
			maxx=max(maxx,q.top().num*(n-q.top().pos+1));
			q.pop();
		}
		printf("%lld\n",maxx);
	}
	return 0;
}

相关文章:

  • 在线副业教程之 02 你学的越多,你赚的越多+你必须开始学习的5个最好的在线副业
  • VUE | key的内部原理、Vue监测数据的原理、Vue.set()和vm.$set()的使用
  • Centos/Docker 环境中文乱码如何解决
  • VS2019 Qt源码编译
  • Linux8-fork父子进程逻辑地址相同、进程的逻辑地址与物理地址、fork相关例题、僵死进程
  • java毕业设计普通中学体育卫生信息管理系统源码+lw文档+mybatis+系统+mysql数据库+调试
  • 基于C语言的查找算法汇编
  • 多网段多通道IP地址和通讯端口转换
  • 【PyQt】PyQt入门安装和Hello World
  • 怎样创建一个VUE项目(超简单)
  • C++【STL】【queue的使用和模拟实现】【priority_queue的使用和模拟实现】
  • SAP PI PO 接口常见问题处理:在监控器中找不到一个或多个 XI 消息的日志记录
  • L2TP客户端之Strongswan移植(三)
  • matplotlib入门之抛砖引玉
  • java-php-python-springboot携手助学助学交流平台计算机毕业设计
  • __proto__ 和 prototype的关系
  • 0x05 Python数据分析,Anaconda八斩刀
  • 2019年如何成为全栈工程师?
  • Angular 4.x 动态创建组件
  • OSS Web直传 (文件图片)
  • v-if和v-for连用出现的问题
  • Vue 动态创建 component
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 简单数学运算程序(不定期更新)
  • 利用DataURL技术在网页上显示图片
  • 前端面试之CSS3新特性
  • 区块链将重新定义世界
  • 三分钟教你同步 Visual Studio Code 设置
  • 通过git安装npm私有模块
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • python最赚钱的4个方向,你最心动的是哪个?
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 阿里云ACE认证之理解CDN技术
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • # Java NIO(一)FileChannel
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • #微信小程序:微信小程序常见的配置传值
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)原始图像数据和PDF中的图像数据
  • **python多态
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .NET 回调、接口回调、 委托
  • .net流程开发平台的一些难点(1)
  • .pop ----remove 删除
  • @Autowired标签与 @Resource标签 的区别
  • @Autowired和@Resource的区别
  • [ 代码审计篇 ] 代码审计案例详解(一) SQL注入代码审计案例