【算法每日一练]-单调队列,滑动窗口(保姆级教程 篇1) #滑动窗口 #求m区间的最小值 #理想的正方形 #切蛋糕

今天讲单调队列

目录

 题目:滑动窗口

思路:

 题目:求m区间的最小值​

思路:

题目:理想的正方形

思路:

题目:切蛋糕       

思路:


      

       

一共两种类型:一种是区间中的最值(滑动窗口),另一种是区间和的最值(切蛋糕),原理一样。

 题目:滑动窗口

        

思路:

    放这个题是为了给出模板。

      

单调队列使用注意事项:(遍历i就要维护[i-k+1,i]的单调区间,从而遍历所有的i)

      
入队新元素为i   过期队头和i-k+1比较即q[h]<i-k+1
队尾出队是a[i]<a[q[t]](取不取等都一样,因为新元素来了都要入队)

队头过期是q[h]+k<i+1

      
1,维持单调:剔除因新来的元素导致的不单调元素
2,队尾入队:新来元素一定入队(以便更新队尾下标,方便和下一个新元素比较)
3,过期出队:队头元素的下标是否越界(和队头指针值无关)

       

#include <bits/stdc++.h>                
using namespace std;
int n,k;
int q1[1000001],q2[1000001],a[1000001];
void min_deque()
{
    int h=1,t=0;//h是头,t是尾(h和t的值没有任何意义,就当成front和back)
    for(int i=1;i<=n;i++)//从第一个数开始滑动
    {                                   //开始对上个元素的队列进行更新
        while(h<=t&&a[i]<a[q1[t]]) t--;//(维持单调)新元素入队后,剔除无效元素
        q1[++t]=i; //新元素入队操作
        if(q1[h]+k<=i) h++;//过期决策从队头出队
        if(i>=k) printf("%d ",a[q1[h]]);//输出最值
    }
    cout<<endl;
}
void max_deque()
{
    int h=1,t=0;
    for(int i=1;i<=n;i++)
    {
        while(h<=t&&a[i]>a[q2[t]]) t--;
        q2[++t]=i;
        if(q2[h]+k<=i) h++;
        if(i>=k) printf("%d ",a[q2[h]]);
    }
}
int main()
{
    cin>>n>>k; //n为长度,k为窗口大小
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    min_deque();//维护两个单调队列
    max_deque();
    return 0;
}

       

        

 题目:求m区间的最小值

         

思路:

      

就是遍历i时候,要创建维护[i-m,i-1]的最小值的单调队列,从而遍历所有的i
入队新元素为i-1     所以h<=t&&a[q[t]]>a[i-1]
过期队头和i-m比较  h<=t&&q[h]+m<i
      

#include <bits/stdc++.h>
using namespace std;
const int N=2e6+5;
int n,m,a[N],q[N];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	int h=1,t=0;
	cout<<0<<'\n';
	for(int i=2;i<=n;i++){
		while(h<=t&&a[q[t]]>a[i-1])t--;
		q[++t]=i-1;
		while(h<=t&&q[h]+m<i)h++;
		cout<<a[q[h]]<<'\n';
	}
	return 0;
}

       

     

题目:理想的正方形

       

思路:

      

之前讲的是一维的区间最值,现在的是二维区间最值,那么维护二维的单调队列即可。

操作:

先对原矩阵进行列压缩,使用单调队列一行一行处理,然后再对压缩后的矩阵进行行压缩,一列一列处理

      
注意事项: 
1,处理完后要从头开始放元素,这时就要注意别让下标越界了!!!
2,注意每个矩阵的行列数,可不一样,别写错了!!!
2,这个写法只针对小矩阵边长不为1 ,当为1时就需要特判处理,在外层循环加上:(memcpy(min2,min1,sizeof(min2));break;)
     

#include <bits/stdc++.h>//P2216:
using namespace std;
int n,m,k,h,H,t,T,ans;
int a[1001][1001],q[1001],Q[1001];//设置两个队列,以便同时完成最大值和最小值,
int x[1001][1001],X[1001][1001];//X,x为第一次压缩后的矩阵
int y[1001][1001],Y[1001][1001];//Y,y为最终最大值和最小值矩阵
void two_deque(){
	for (int i=1;i<=n;i++)//按行来处理(列压缩)同时处理最大值和最小值,不然一共要处理4次
		{
			H=T=h=t=Q[1]=q[1]=1; //同时完成最大值矩阵和最小值矩阵的行压缩
			for (int j=2;j<=m;j++)
				{
					while (a[i][j]>=a[i][Q[T]]&&H<=T) T--;//维持单调性(剔除元素,可以不加等号)
					while (a[i][j]<=a[i][q[t]]&&h<=t) t--;
					Q[++T]=j;q[++t]=j;//新元素一定入队
					while (j-Q[H]>=k) H++;//过期出队
					while (j-q[h]>=k) h++;
					if (j>=k) X[i][j-k+1]=a[i][Q[H]],x[i][j-k+1]=a[i][q[h]];
				}
		}
	for (int j=1;j<=m-k+1;j++)//按列来(注意列变少了)
		{
			H=T=h=t=Q[1]=q[1]=1;   //同时完成最大值矩阵和最小值矩阵的列压缩
			for (int i=2;i<=n;i++)
				{
					while (X[i][j]>=X[Q[T]][j]&&H<=T) T--;
					while (x[i][j]<=x[q[t]][j]&&h<=t) t--;
					Q[++T]=i;q[++t]=i;
					while (i-Q[H]>=k) H++;
					while (i-q[h]>=k) h++;
					if (i>=k) Y[i-k+1][j]=X[Q[H]][j],y[i-k+1][j]=x[q[h]][j];
				}
		}
}
int main()
{
	scanf("%d%d%d",&n,&m,&k);//n,m为矩阵大小,k为需要输出的正方形大小(输出所有方形中极差的最小值)
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	
	two_deque();		
    ans=0x3f3f3f3f;
	for (int i=1;i<=n-k+1;i++)
		for (int j=1;j<=m-k+1;j++)
			ans=min(ans,Y[i][j]-y[i][j]);
	printf("%d\n",ans);
	return 0;
}

     

      

题目:切蛋糕

       

思路:

     

首先我们这道题是要不定长的前缀和,最优前缀和是max{sum[i]−sum[j],0}(i-j<=m),我们按题意固定i后就是max(0,sum[i]−min{sum[j]})。

也就是我们只需要维护[i-m+1,i]中最小的sum[j]即可,但是窗口右固定大小,所以要剔除过期的决策
      

#include<bits/stdc++.h>           
using namespace std;
const int N=5e5+10,INF=1e9;
int sum[N],q[N],ans=-INF;//注意有可能有负数 
int main()
{
	int n,m;scanf("%d%d",&n,&m); //n为蛋糕块数,m为窗口大小
	for (register int i=1;i<=n;++i)
	{
		int x;scanf("%d",&x);
		sum[i]=sum[i-1]+x;//求前缀和 
	}
	int head=1,tail=1;q[1]=0;
	for (register int i=1;i<=n;++i)
	{                                     //对上个元素的队列处理
		while (head<=tail&&q[head]+m<i+1) head++;//过期的最优决策出队 ,这里不能取等哦
		while (head<=tail&&sum[i]<=sum[q[tail]]) tail--;//(维持单调)新元素i入队会使一些元素“无效 ”
		q[++tail]=i;
		ans=max(ans,sum[i]-sum[q[head]]);
	}
	printf("%d\n",ans);
	return 0;
}

也可这样

//  也可以这么写,(<queue>头文件)  
//访问:front,back  操作:pop_front,pop_back,push_front;push_back
	deque<int>q; //deque是双向队列
    q.push_back(0);
    for(int i=1;i<=n;i++)
    {	
        while(!q.empty()&&q.front()+m<i) q.pop_front();//越界就pop
        ans=max(ans,sum[i]-sum[q.front()]);
        while(!q.empty()&&sum[q.back()]>=sum[i])  q.pop_back();//递减就pop
        q.push_back(i);
    }

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

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

相关文章

游戏制作:猜数字(1~100),不会也可以先试着玩玩

目录 1 2代码如下&#xff1a;可以试着先玩玩 3运行结果&#xff1a;嘿嘿嘿 4程序分析&#xff1a;想学的看 5总结&#xff1a; 1 猜数范围为1~100&#xff0c;猜大输出猜大了&#xff0c;猜小输出猜小了&#xff0c;游戏可以无限玩。 首先先做一个简单的菜单界面&#xf…

RK3588平台 WIFI的基本概念

一.安卓WIFI框架 Android WIFI系统引入了wpa_supplicant&#xff0c;它的整个WIFI系统以wpa_supplicant为核心来定义上层接口和下层驱动接口。Android WIFI主要分为六大层&#xff0c;分别是WiFi Settings层&#xff0c;Wifi Framework层&#xff0c;Wifi JNI 层&#xff0c; W…

WorkPlus Meet:局域网内部使用的高效视频会议系统

随着全球化和远程办公的趋势&#xff0c;视频会议已成为现代企业和机构不可或缺的沟通工具。而现在&#xff0c;大多数政企单位或者涉密强的企业&#xff0c;都会使用局域网部署的音视频会议系统&#xff0c;提供更高的安全性和隐私保护。因为音视频会议中可能涉及到公司机密和…

Torch Hub 系列#2:VGG 和 ResNet

一、说明 在上一篇教程中,我们了解了 Torch Hub 背后的本质及其概念。然后,我们使用 Torch Hub 的复杂性发布了我们的模型,并通过相同的方式访问它。但是,当我们的工作要求我们利用 Torch Hub 上提供的众多全能模型之一时,会发生什么? 在本教程中,我们将学习如何利用称为…

自动泊车轨迹规划学习

1.基于6次多项式的自动泊车轨迹算法研究 针对常见的自动泊车系统无法躲避障碍物&#xff0c;以及轨迹的曲率不连续等问题进行了泊车轨迹算法的研究以及跟踪算法的设计。 针对低速自动泊车场景进行分析&#xff0c;建立符合对应场景下的车辆运动学模型以及能够泊车的最小车位大…

华为dns mapping配置案例

解决内网PC用公网的dns用域名方法访问公司内网的web服务器&#xff1a; 原理是用DNS mapping方式解决 配置过程&#xff1a;域名——出口公网IP地址——公网端口——协议类型 公司内网client用户填公网dns&#xff0c; 公网上的dns上面已注册有公司对外映射的web服务器的公网…

山西电力市场日前价格预测【2023-11-13】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-13&#xff09;山西电力市场全天平均日前电价为428.16元/MWh。其中&#xff0c;最高日前电价为751.89元/MWh&#xff0c;预计出现在18: 30。最低日前电价为289.03元/MWh&#xff0c;预计…

【MySQL系列】 第一章 · MySQL概述

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

王道 | 数据结构第一章

目录结构 章节总览 1.0 开篇_数据结构在学什么 1.1_1 数据结构的基本概念 1.1_2 数据结构的三要素 1.2_1 算法的基本概念 1.2_2 算法的时间复杂度 1.2_3 算法的空间复杂度 章节总览 1.0 开篇_数据结构在学什么 1.1_1 数据结构的基本概念 数据&#xff1a; 数据是信息的载…

数据库加密的常用方法 安当加密

数据库加密的方法主要有以下几种&#xff1a; 前置代理及加密网关技术&#xff1a;在数据库之前增加一道安全代理服务&#xff0c;对数据库访问的用户都必须经过该安全代理服务&#xff0c;在此服务中实现如数据加解密、存取控制等安全策略。加密数据存储在安全代理服务中。但…

OpenCV:图像旋转与缩放

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

人工智能基础——图像认知与OpenCV

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

Adversarial Training Methods for Deep Learning: A Systematic Review

Adversarial Training Methods for Deep Learning: A Systematic Review----《面向深度学习的对抗训练方法:系统回顾》 摘要 通过快速梯度符号法(FGSM)、投影梯度下降法(PGD)和其他攻击算法&#xff0c;深度神经网络暴露在对抗攻击的风险下。对抗性训练是用来防御对抗性攻击威…

DBeaver:强大实用的跨平台数据库工具 | 开源日报 No.71

dbeaver/dbeaver Stars: 34.3k License: Apache-2.0 DBeaver 是一个免费的多平台数据库工具&#xff0c;适用于开发人员、SQL 程序员、数据库管理员和分析师。它支持任何有 JDBC 驱动程序的数据库&#xff0c;并且商业版本还支持非-JDBC 数据源 (如 MongoDB、Cassandra 等)。该…

pandas笔记:读写excel

1 读excel read_excel函数能够读取的格式包含&#xff1a;xls, xlsx, xlsm, xlsb, odf, ods 和 odt 文件扩展名。 支持读取单一sheet或几个sheet。 1.0 使用的数据 1.1 主要使用方法 pandas.read_excel(io, sheet_name0, header0, namesNone, index_colNone, usecolsNon…

基于Matlab+ AlexNet神经网络的动物识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Matlab和AlexNet神经网络的动物识别系统可以用于自然图像识别等场景&#xff0c;以下是一个基本的介绍设计步骤…

ASAM OpenDRIVE V1.7协议超详解(一)

文章目录 前言一、仿真场景的构成二、openDRIVE框架三、g_additionalData四、openDRIVE-header五、openDRIVE-road1、Road总拓扑结构2、Road-link介绍1&#xff09;link的拓扑结构2&#xff09;link链接示例3&#xff09;link前继后继4&#xff09;道路link规则 3、road-type介…

No182.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

eocc1_Findings_candlestick_ohlc_volume_

An Unusually Tall Candle Often Has a Minor High or Minor Low Occurring within One Day of It异常高的蜡烛通常会在一天内出现小幅高点或小幅低点 I looked at tens of thousands of candles to prove this, and the study details are on my web site, ThePatternSite.com…

软件架构的可维护性指标——代码圈复杂度

代码圈复杂度 1、目的2、前言3、简介4、案例5、降低6、插件7、总结 1、目的 区别于常规的高内聚、低耦合、抽象、封装这种定性的指标&#xff0c;我想通过对软件架构可维护性的可量化的指标的分享&#xff0c;帮助大家在日常的开发工作中&#xff0c;有一个更为广阔的视角去审…