HDU Maximal submatrix(单调栈/悬线法)

告别手动打点!用Cesium为你的大疆无人机快速生成区域巡查航线(保姆级教程) 本文详细介绍了如何利用Cesium平台为大疆无人机快速生成区域巡查航线的保姆级教程。通过自动化航线规划,告别传统手动打点的繁琐操作,实现高效、无死角的区域覆盖。文章涵盖环境搭建、实战案例及高级优化技巧,特别适合无人机操作员和巡检工作者提升工作效率。 阅读详情

目录

单调栈

悬线法


题目链接:Problem - 6957 (hdu.edu.cn)

题意:输入一个n行m列的矩阵,找到每一列非递减的最大子矩形面积。

知识点

方法一:单调栈

1.单调栈定义:

(1)单调递增栈:单调递增栈就是从栈底到栈顶数据是从大到小

(2)单调递减栈:单调递减栈就是从栈底到栈顶数据是从小到大

2.单调栈解法:

(1)首先预处理出自该位置向上满足性质的数的个数,记为 h[i][j]。

(2)对于每行 (h[i]) 维护一个单调递增栈,所有元素进栈和出栈一次,每个元素出栈时更新最大的矩形面积。

(3)为了能够更新最大的矩形面积,我们需要在栈内记录两个数据——元素的高度 h[i][j] 和它到栈中上一个元素的宽度差。

(4)元素出栈时,因为高度逐渐递减,故记width 为当前已经弹出的元素的宽度和。

3.求常见应用:柱状图中的最大面积/离线RMQ问题/优化DP

方法二:悬线法

1.适用范围:悬线法的适用范围是单调栈的子集。具体为:

  • 需要在扫描序列时维护单调的信息;
  • 可以使用单调栈解决;
  • 不需要在单调栈上二分。

2.用于解决的问题有:最大子矩阵问题

例如:在一条水平线上有 n个宽为1 的矩形,求包含于这些矩形的最大子矩形面积。

3.具体方法

参考:悬线法 - OI Wiki (oi-wiki.org)

       悬线,就是一条竖线,这条竖线有初始位置和高度两个性质,可以在其上端点不超过当前位置的矩形高度的情况下左右移动。

       对于一条悬线,我们在这条上端点不超过当前位置的矩形高度且不移出边界的前提下,将这条悬线左右移动,求出其最多能向左和向右扩展到何处,此时这条悬线扫过的面积就是包含这条悬线的尽可能大的矩形。容易发现,最大子矩形必定是包含一条初始位置为 i,高度为 hi 的悬线。枚举实现这个过程的时间复杂度为O(n^2) ,但是我们可以用悬线法将其优化到 O(n)。

        定义li为当前找到的i位置的悬线能扩展到的最左边的位置,容易得到li初始为i,我们需要进一步判断还能不能进一步往左扩展。

  • 如果当前 li=1,则已经扩展到了边界,不可以。
  • 如果当前 hi>hli-1,则从当前悬线扩展到的位置不能再往左扩展了。
  • 如果当前 hi<=hli-1 ,则从当前悬线还可以往左扩展,并且li-1位置的悬线能向左扩展到的位置,i位置的悬线一定也可以扩展到,于是我们将 li 更新为 lli-1 ,并继续执行判断

       对于ri也同理。

悬线法求最大矩形代码:

#include<iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
#define  N 100010//最大矩形宽度
int n;//矩形个数
int h[N];//每个矩形高度
int l[N], r[N];//i位置的悬线能扩展到的最左边的位置和最右边的位置
long long ans;
int main() 
{
	cin >> n;
    ans = 0;
	for (int i = 1; i <= n; i++)
	{
		cin >> h[i];
		l[i] = r[i] = i;
	}
		for (int i = 1; i <= n; i++)
			while (l[i] > 1 && h[i] <= h[l[i] - 1]) 
				l[i] = l[l[i] - 1];
		for (int i = n; i >= 1; i--)
			while (r[i] < n && h[i] <= h[r[i] + 1]) 
				r[i] = r[r[i] + 1];
		for (int i = 1; i <= n; i++)
			ans = max(ans, (long long)(r[i] - l[i] + 1) * h[i]);//最左位置到最右位置乘上本身高度即为矩形面积
		printf("%lld\n", ans);
    return 0;
}

本题代码:

1.预处理出自该位置向上满足性质的数的个数,记为 h[i][j]。

2.用悬线法求最大矩形。

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define maxn 2005
int v[maxn][maxn];
int h[maxn][maxn];
int l[maxn][maxn];//i行j列的悬线最左到达位置
int r[maxn][maxn];//i行j列的悬线最右到达位置
void solve()
{
	int n, m;
	int ans = 0;
//记录自该位置向上满足性质的数字
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			scanf_s("%d",&v[i][j]);
			h[i][j] = 1;
			l[i][j] = r[i][j] = j;//初始化
		}
	for(int j=1;j<=m;j++)
		for (int i = 1; i < n; i++)
		{
			if (v[i][j] <= v[i + 1][j])
				h[i + 1][j] = h[i][j] + 1;
		}
	//求左位置:从左开始求
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			while (l[i][j] > 1 && h[i][j] <= h[i][l[i][j] - 1])
				l[i][j] = l[i][l[i][j] - 1];		
		}
	//求右位置:从右开始求
	for(int i=1;i<=n;i++)
		for (int j = m; j >= 1; j--)
		{
			while (r[i][j] < m && h[i][j] <= h[i][r[i][j] + 1])
				r[i][j] = r[i][r[i][j] + 1];
		}
	//求最大矩形
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			ans = max(ans, (r[i][j] - l[i][j] + 1) * h[i][j]);
		}
	}
	cout << ans << endl;
}
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
}

【北大核心-代码复现】基于 VMD-FFCM-iTransformer 光伏功率短期预测 阅读详情

相关推荐

ARM Cortex-M系列授权解析:从研发到量产的免费与付费之路

本文深入解析了ARM Cortex-M系列内核从研发到量产过程中的授权模式。研发阶段可利用ARM DesignStart等免费资源进行原型验证,但产品商业化量产则需支付授权费与版税。文章对比了采购商用MCU与自研芯片的成本差异,并探讨了RISC-V作为免费替代方案在IoT领域的应用前景与挑战,为开发者提供了清晰的选型指南。

weixin_29292431的博客 494

Maximal submatrix(直方图最大矩阵)

Maximal submatrix 原题链接 先预处理出每个点的高度,对于每一行而言就是一个直方图。然后利用单调栈对于每一行求出面积最大的矩阵,其实就和最大面积全 111 矩阵问题是一样的。原理都是,对于一个直方图而言,其面积最大的矩阵的高度一定会卡在某个横坐标的上限,不然的话一定会有面积更大的矩阵,也就是不然高度一定可以往上涨。基于这个原理,我们就去遍历横坐标,假设高度上限在这,然后计算出向左向右最多能扩张到哪里,这里就要利用单调栈了。然后最后对于每个横坐标我们都求出了以此为上限的最大可能面积,答案就.

qq_45863710的博客 462

Linux中断子系统分析之(四):驱动程序申请中断

中断子系统中有一个重要的设计机制,那就是Top-half和Bottom-half,将紧急的工作放置在Top-half中来处理,而将耗时的工作放置在Bottom-half中来处理。 如果中断不分上下半部处理,那么意味着只有等上一个中断完成处理后才会打开中断,下一个中断才能得到响应。当某个中断处理处理时间较长时,很有可能就会造成其他中断丢失而无法响应,影响系统性能。 中断分成上下半部处理可以提高中断的响应能力,在上半部处理完成后便将中断打开,这样就可以响应其他中断了,等到中断退出的时候再进行下半部的处理。为了进

m0_46525308的博客 1225

Maximal submatrix(悬线法)

这道题实质是就是求一个最大子矩阵,参考了很多悬线法的代码,这里介绍一个我感觉很妙的方式,首先我们要知道什么是悬线法: 悬线,就是一条竖线,这条竖线要满足其上端点在矩形的上边界或其上端点的上面是障碍点。我们枚举每个点的悬线,求出其最多能向左和向右扩展到何处,取最大值,就能求出最大子矩阵了。 通俗的说就是你有一条线,这条线的长度固定,可以左右移动,看他最多能扫过的面积就是我们要求的最大子矩阵的面积。 我们可以对已知矩阵进行预处理: up[i][j]: 坐标是(i,j)的这个点最大可以往上的长度,因为要求每一.

daq0411的博客 737

淘特App x-sign参数逆向实战:从抓包到算法定位

本文详细解析了淘特App的x-sign参数逆向过程,从抓包分析到算法定位,涵盖了使用jadx-gui进行静态分析、Frida动态Hook验证以及Native层算法还原等关键技术。文章重点介绍了x-sign参数的生成机制及其在阿里系应用中的安全防护策略,为逆向工程师提供了实用的调试技巧和对抗策略。

5b6n7m8的博客 227

【DSP】【工程实战】从零构建C6678多核工程:CCS环境配置与启动模式详解

本文详细介绍了在CCS开发环境中从零构建TMS320C6678多核DSP工程的完整流程。内容涵盖KeyStone架构解析、工程创建、基础代码编写、链接命令文件配置、仿真器调试,并重点深入讲解了包括I2C EEPROM在内的多种一级启动模式原理与配置方法,为开发者提供了一套清晰、可复用的实战指南。

weixin_29164185的博客 416

HDU 6957 Maximal submatrix(悬线法 || 优先队列 || 单调栈 )

目录问题分析代码 问题 HDU 6957 Maximal submatrix - https://acm.hdu.edu.cn/showproblem.php?pid=6957 分析 悬线法 dp 代码 悬线法【2012MS】 #include<bits/stdc++.h> using namespace std; #define MXN 2010 int n, m, ans; int v[MXN][MXN], h[MXN][MXN], l[MXN][MXN], r[MXN][MX

jpphy0的博客 532

Windows本地部署Qwen3-14B实战指南:Ollama+Open WebUI零Docker方案

大语言模型本地部署是AI工程化落地的关键环节,其核心在于推理框架兼容性、硬件加速适配性与端到端稳定性。Ollama作为轻量级模型运行时,原生支持Windows DirectML与CUDA,规避了Docker/WSL2虚拟化开销和llama.cpp编译风险;Qwen3-14B则凭借128K上下文、Tool Calling原生支持及中文长文本结构化能力,成为政务、金融等场景首选。本文聚焦Windows平台真实约束——显存阈值、驱动版本匹配、路径编码兼容、离线知识库集成(RAG)等工程细节,提供经63台Windo

weixin_32136203的博客 412

Maximal submatrix (悬线,单调栈)

2021“MINIEYE杯”中国大学生算法设计超级联赛(1) Maximal submatrix 方法1悬线:由于题目是每一列一段区间,不好看,先把矩阵倒置变换 在进行 行间变换时,条件是两者同时足a[i] [j] <= a[i] [j+1] && a[i-1] [j] <= a[i-1] [j+1] #include <bits/stdc++.h> using namespace std; const int N=2003; int n,m,a[N][N],h

yezzz的博客 199

2025年上半年第1批信息系统项目管理师论文真题解析与范文

文章首先分析了项目经理在交付绩效域中应关注的重点领域,然后按照项目管理五大过程组顺序,阐述了各过程组中与交付绩效域协同的绩效域及协调目标,最后制定了各过程组中交付绩效域的测量指标。本项目的实践表明,系统化的交付绩效管理不仅能保证项目成功,还能创造超出预期的业务价值。需要结合具体项目案例,按照五大过程组(启动、规划、执行、监控、收尾)顺序,分析各过程组中与交付绩效域协同的其他绩效域及其协调目标。价值交付连续性:建立敏捷交付机制,将项目分解为12个迭代周期,每周期交付可验证成果,确保价值持续流动。

Programming Talk 819

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

hdu 3410 单调栈

Description 现在有n个人站成一行,告诉你每个人的身高。 现在每个人都要找到在他左边,比他矮的人中最高的人的位置。 同时也要找到,在他右边比他矮的人中最高的人的位置。 注意由于他们是站成一行的,所以他们不能越过比他们高的人去看后面的人。也就是说,他只能看到他本人和他的左边(或右边)第一个比他高的人之间的那些人。 请输出每个人左边比他矮的人中最高的人的位置,以及每个人的右边比

Marcus-Bao的个人主页 1583

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

悬线法,单调栈解决 HDU6957 Maximal submatrix

悬线法可以用来解决最大子矩阵等问题 模板题目:https://www.luogu.com.cn/problem/SP1805 大意:在一条水平线上有n个宽为1的矩形,求包含于这些矩形的最大子矩形面积。 代码 /* l[i]:为当前位置i的悬线能扩展到的最左边的位置,初始为i ,我们需要进一步判断还能不能进一步往左扩展。 如果当前l[i]==1 ,则已经扩展到了边界,不可以。 如果当前a[i] > a[l[i] - 1],则从当前悬线扩展到的位置不能再往左扩展了。 如果当前a[i] <= a[l[

glide的博客 240

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

悬 线 法

悬线法:求满足某条件的极大子矩阵,比如“面积最大的长方形、正方形”“周长最长的矩形等等”。 一般用于求 n ✖ m 的01矩阵中面积最大全为1的子矩阵的面积,时间复杂度O(nm) 例题 P1169-ZJOI2007-棋盘制作 P4147 玉蟾宫 P2701 - USACO5.3 - 巨大的牛棚Big Barn P1387 最大正方形 ...

cosx_的博客 315

H - Maximal submatrix HDU - 6957

H - Maximal submatrix HDU - 6957 题意: 给定一个n行m列的矩阵,求每列上面积不减的最大子矩阵 对于每个测试用例,打印一个表示最大子矩阵的整数 题解: 要求求一个最大面积的满足每列非递减的矩阵,这怎么想? 我们可以转化成01矩阵,每一个位置1表示该位置比上面一位大,然后求最大的01矩阵就可以了,单调栈做法时注意0的话可以作为矩阵的开始,详细看看代码 代码: 单调栈做法 #include<bits/stdc++.h> #define debug(a,b) print

qq_35975367的博客 527

求01矩阵最大面积Maximal submatrix HDU - 6957

Given a matrix of n rows and m columns,find the largest area submatrix which is non decreasing on each column Input The first line contains an integer T(1≤T≤10) representing the number of test cases. For each test case, the first line contains two integ

qq_53680405的博客 491

HDU 6957.Maximal submatrix

Issue: Thinking: 题目要求最大子矩阵的面积,就可以把每一行看做是直方图中最大矩形问题,这题马氏风格,暴力枚举每一行 把每一行中非递减的“矩形”用h[][]数组存下来,这样每一行都是一个直方图中最大矩形问题 问题转化为直方图中最大矩形问题,依次枚举每一列,算出每一列能够向左和向右能够到达的最大长度分别用l[]和r[]数组记录,这一步就可以用单调栈来优化,时间复杂度为O(n) 每一行的公示就是(h[i] * (l[i] + r[i] - 1)) 最后,对每一个结果取max 别忘了多组数据测试

qq_46907547的博客 344

HDU6957 Maximal submatrix (单调栈)

题目链接: Maximal submatrix 大致题意 给定一个n×mn \times mn×m的矩阵, 求满足要求的最大面积子矩阵. 要求: 该子矩阵的每一列从上向下看不递减. 解题思路 ➡️题目弱化版点这里⬅️ 单调栈 如果你做过了题目的弱化版, 你会发现这个题实际上是一个二维版本. 我们需要对于每一行都求一次答案即可. AC代码 #include <bits/stdc++.h> #define rep(i, n) for (int i = 1; i <= (n); ++i) usi

Fau的博客 250

HDU6957 Maximal submatrix(DP)

题目链接 转化一下,标记a[i][j]>=a[i-1][j]的位置为1 ,代表可以取。然后求最大全1子矩阵面积。用单调栈/悬线法dp 都是N*M复杂度。 对于单调栈,我们用一个m+1 制造一个虚拟矩阵,为了防止RE以及清空栈。 每次出栈更新的是比当前连续1数目多的那个位置(相当于以第i行作为最底层,用h[j] 标记第j列中当前已经连续的高度) 更新范围为【栈顶,当前)以栈顶为高度的矩阵面积 ll a[2010][2010]; ll b[2010][2010]; ll h[2222]; ll

weixin_45948940的博客 304

[hdu多校] Maximal submatrix

单调栈+dp解决子矩阵问题,细节还是挺多的 #include<bits/stdc++.h> using namespace std; const int maxn=2e3+20; int a[maxn][maxn]; int up[maxn][maxn]; int stk[maxn],top; int T; int main() { scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&am

qq_28972011的博客 169

HDU - 6957 - Maximal submatrix( 单调栈 )

题目链接:点击进入 题目 题意 一个 n * m 的矩阵,让你找出每列非递减的最大的子矩阵。 思路 跟找全 1 矩阵很相似,记录一个 h 数组,对于每个位置,记录它所在这列它的上方最长非递减序列的长度( 算上它本身 ),这个 h 数组,就相当于宽为 1 的 每列非递减 的子矩阵的高度,剩下的就是遍历每一行,用单调栈求每一行的最大每列非递减子矩阵。 代码 #include<iostream> #include<string> #include<map> #include&

Cosmic_Tree的博客 258

HDU 6957 Maximal submatrix (单调栈,柱形图最大矩阵面积)

题目:Problem - 6957 (dingbacode.com) 题目大意是给出一个矩阵,找出面积最大的子矩阵,这个子矩阵的每一列上的数字都要是非递减的。 直接处理非常麻烦,所以先进行预处理,提前处理出每一列(第j列)上以第i个开始的非递减数列长度b[i][j],再用扫描线从1到n扫一遍,处理出以第i行为底边的最大矩阵面积,这样就把题目转变为求柱形图的最大矩阵面积了。 然后用单调栈维护答案即可。 代码: #include<iostream> #inc...

qq_53333451的博客 233

2021hdu多校1 Maximal submatrix(单调栈+简单dp)

**题意:**给你一个数字矩阵,让你找一个子矩阵,使其满足每一列是非递减的,输出最大的子矩阵的面积。 题解: 我们根据每一列进行非递减的dp,得到dp是以当前点为结尾的最大非降子序列。 然后根据我蓝书中一道单调栈的题(传送门),我们可以将每一行的dp当做矩形的高,矩形的宽为1,直接单调栈即可完成计算 code: #include <bits/stdc++.h> using namespace std; typedef long long ll; const double PI = acos

246

【HDU】2021杭电暑假集训营(第一场):Maximal submatrix 单调栈

传送门 题意 求一个最大的矩阵面积,要求这个矩阵的每一列都是不下降的 分析 我们去维护每一列满足条件的长度,如果 代码 #pragma GCC optimize(3) #include <bits/stdc++.h> #define debug(x) cout<<#x<<":"<<x<<endl; #define dl(x) printf("%lld\n",x); #define di(x) printf("%d\n",x); #define _C

tlyzxc的博客 196

2021HDU多校训练赛(1)1008

2021HDU多校训练赛(1)1008(HDU6957)Maximal submatrix 链接: HDU6957 题目大意: 给你一个矩阵,输出最大的列不下降的子矩阵。 题解: 题目经预处理每个点的最长不下降序列之后可以转化为求直方图中的最大矩形 (该图片源链接来自@ojzha_gcx 原文链接) 求直方图最大矩形可以使用单调栈前后跑两次,也可以使用悬点法dp,代码如下 #include<bits/stdc++.h> #define ll long long using namespace

qq_52402041的博客 348

2021.杭电中超 第一场.补题

1001 https://acm.hdu.edu.cn/showproblem.php?pid=6950 签到,打表找规律就好了。 1005 Minimum spanning tree https://acm.hdu.edu.cn/showproblem.php?pid=6954 思维题,签到 大意:现有 n 个点 (2<=n<=10000000),任意两点a,b之间的之间的权重为 lcm(a,b)。求最小生成树。 思路:对于最小公倍数,最好的情况下就是较大的那个数本身,显然对于一个.

m0_51488693的博客 284

【HDU 5033】【经典单调栈问题】Building

题意: n个人,n栋楼,问每个人往左看,往右看,能够看到的天空的最大角度。 【这是一个很经典的单调栈问题】 思路: 首先,能够想到将人和楼全部读入栈中进行统一处理。并且左边跑一次单调栈,求出人能够往左看到的最高的楼。右边跑一次,处理出人能够往右看到的最高的楼房。【reverse(a+1,a+1+num)即可换方向再跑一遍】 问题在于如何处理出每个人能够看到的...

lucius-liu.cn 525
上一篇: Hdu KD-Graph(并查集、Kruscal算法)
下一篇: HDU I love counting(莫队+字典树)
Asiip
博客等级 码龄7年 1粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值