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

news2024/11/19 7:45:09

今天讲单调队列

目录

 题目:滑动窗口

思路:

 题目:求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);
    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第四十九天|121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II

第九章 动态规划part10 121. 买卖股票的最佳时机 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最…

C语言证明一个偶数总能表示为两个素数之和。输入一个偶数并将其分解为两个素数

完整代码&#xff1a; // 一个偶数总能表示为两个素数之和。输入一个偶数并将其分解为两个素数#include<stdio.h>//判断一个数n是否为素数 int isPrimeNumber(int n){//1不是素数if (n1){return 0;}for (int i 2; i <(n/2); i){//当有n能被整除时&#xff0c;不是素…

吃透 Spring 系列—IOC部分

目录 ◆ 传统Javaweb开发的困惑 -传统Javaweb开发代码分析-用户模块 -传统Javaweb开发困惑及解决方案 ◆ IoC、DI和AOP思想提出 - IoC 控制反转思想的提出 - DI 依赖注入思想的提出 - AOP 面向切面思想的提出 - 框架概念的出现 - 思想、框架和编码关系 ◆ Spring框架…

UML软件建模软件StarUML mac中文版软件介绍

StarUML for mac是一款UML建模器&#xff0c;StarUML for mac提供了几个模版&#xff0c;帮助用户建立使用新的图表&#xff0c;是目前最流行的UML建模工具&#xff0c;给开发工作带来大大的便利。 StarUML mac软件介绍 StarUML 是一个流行的软件建模工具&#xff0c;用于创建…

[vuex] unknown mutation type: SET_SOURCE

项目中使用了vuex&#xff0c;并且以模块的形式分好之后。在调用的时候出现了以上问题 /*当我们commit的时候要注意要加上模块的名字 user是模块名称&#xff0c;SET_SOURCE是user模块中定义的方法 正确写法&#xff1a;*/ this.$store.commit("user/SET_SOURCE", th…

Java14新增特性

前言 前面的文章&#xff0c;我们对Java9、Java10、Java11、Java12 、Java13的特性进行了介绍&#xff0c;对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 今天我们来一起看一下Java14这个版本的一些重要信息 版本介绍 Java 14…

自动泊车轨迹规划学习

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

JavaWeb Day10 案例 准备工作

目录​​​​​​​ 一、需求说明 二、环境搭建 &#xff08;一&#xff09;数据库 &#xff08;二&#xff09;后端 ①controller层 1.DeptController.java 2.EmpController.java ②mapper层 1.DeptMapper.java 2.EmpMapper.java ③pojo层 1.Dept.java 2.Emp.jav…

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

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

S32K3基础学习 linker链接器脚本ld文件的学习(一)

一、简介 最近学习NXP新推出的S32K3系列芯片&#xff0c;我在学习容易转牛角尖&#xff0c;非得要搞明白这个芯片的启动流程&#xff0c;所以花费了一些时间&#xff0c;进行查阅资料进行学习&#xff0c;这里做下详细的记录&#xff0c;希望有用&#xff0c;如果有错误欢迎指正…

Springboot+vue的毕业生实习与就业管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的毕业生实习与就业管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点…

dream_ready

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对这篇博客也感兴趣o (ˉ▽ˉ&#xff1b;) Python 语法及入门 &#xff08;超全超详细&#xff09; 专为Python零基础 一篇博客让你完全掌握Python语法 路的尽头是什么&#xff1f;这是我年少时常伴在嘴…

Runway 最强竞品 Pika 1.0 预告来袭!文生视频效果堪比迪士尼动画!重新定义动画生成新范式!

作者 | 张雨霏、王二狗 Runway是AI生成视频赛道的绝对霸主吗&#xff1f; 不一定&#xff01; 就在这两天天&#xff0c;Pika在推特上官宣——Pika 1.0即将来袭&#xff01; 网友看到后都直呼 Amazing &#x1f929;&#xff01;Unexpected! &#x1f525; 还有网友表示未来…

路径总和[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你二叉树的根节点root和一个表示目标和的整数targetSum。判断该树中是否存在 根节点到叶子节点的路径&#xff0c;这条路径上所有节点值相加等于目标和targetSum。如果存在&#xff0c;返回true&#xff1b;否则&#xff0c;返回fa…

2016年408计网

这一年&#xff0c;计算机网络部分的全部考题都围绕该网络拓扑图进行。 第33题 在 OSI 参考模型中, R1、Switch、Hub 实现的最高功能层分别是() A. 2、2、1 B. 2、2、2 C. 3、2、1 D. 3、2、2 本题考察路由器、以太网交换机、集线器各自实现的最高功能层是什么题目给定R1是…

王道 | 数据结构第一章

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

Linux应用开发基础知识——LCD上的矢量字体Freetype(六)

前言&#xff1a; 使用 buildroot 来给 ARM 板编译程序、编译库会很简单&#xff0c;以后系统讲解 buildroot 时再使用 buildroot&#xff0c;现在我们还是手工交叉编译 freetype&#xff0c;这种方法在编译、安装一些小程序时很有用。 Freetype 是开源的字体引擎库&#xff0c…

文生图模型测评之HPS v2

文章目录 1. 简介2. HPD v22.1 相关数据集介绍2.2 HPD v2 的构建2.2.1 prompt collection2.2.2 image collection2.2.3 preference annotation3. Human Preference Score v23.1 构建模型3.2 实验结果4. 结论及局限性论文链接:Human Preference Score v2: A Solid Benchmark fo…

目标检测——Yolo系列(YOLOv1/2/v3/4/5/x/6/7/8)

目标检测概述 什么是目标检测&#xff1f; 滑动窗口&#xff08;Sliding Window&#xff09; 滑动窗口的效率问题和改进 滑动窗口的效率问题&#xff1a;计算成本很大 改进思路 1&#xff1a;使用启发式算法替换暴力遍历 例如 R-CNN&#xff0c;Fast R-CNN 中使用 Selectiv…

【2011年数据结构真题】

41题 41题解答&#xff1a; &#xff08;1&#xff09;图 G 的邻接矩阵 A 如下所示&#xff1a; 由题意得&#xff0c;A为上三角矩阵&#xff0c;在上三角矩阵A[6][6]中&#xff0c;第1行至第5行主对角线上方的元素个数分别为5, 4, 3, 2, 1 用 “ 平移” 的思想&#xff0c;…