【算法每日一练]-单调队列(保姆级教程 篇2)#琪露诺 #选数游戏 #寻找段落

news2025/1/12 1:52:19

最后一期单调队列了啊

目录

题目:琪露诺

 思路:

题目:选数游戏

思路: 

题目:寻找段落

思路:


        

        

之前做的都是连续的长度区间求最值,今天体验一下不连续的区间。

然后就是要注意维护单调队列时维护的是哪个数组?在的哪个区间?

        

题目:琪露诺

       

 思路:

     

首先f[i]表示走到i格子时获得最大和:f[i]=max(f[i-r]~f[i-l])+v[i]

常规做法O(n^2)会超时  那就维护f数组[i-r,i-l]的单调队列,当遍历i时,维护f[i-r,i-l]的最大值的单调队列,不是原数组v!!!

     
入队新元素为i-l  所以h<=t&&f[q[t]]<f[i-l],队尾才能出队,然后i-l入队
队头过期元素和i-r比较  所以h<=t&&q[h]<i-r,队头下标比i-r还小就要丢掉
更新f[i]:f[i]=f[q[h]]+v[i]
      

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+86;
int n,f[N],l,r,ans=-0x3f3f3f3f,v[N],q[N],h=1,t=0;//其实h和t的值不重要,只要h==t就是队中仅1个元素,h>t队空,里面存放的下标才是关键
//有负数所以 ans 初始化为负无穷
int main()
{	
	memset(f,-0x3f,sizeof(f));f[0]=0;
	scanf("%d%d%d",&n,&l,&r);
	for(int i=0;i<=n;i++)
		scanf("%d",&v[i]);
	for(int i=l;i<=n;i++)//遍历到i时,我们的新入队元素应该是i-l,不是i
	{
		while(h<=t&&q[h]<i-r) h++;//过期队头出队
		while(h<=t&&f[q[t]]<f[i-l]) t--;//维护[i-r,i-l]的单调最值
		q[++t]=i-l;//新元素i-l入队
		f[i]=f[q[h]]+v[i];//从最值中取出更新f[i]
		if(i+r>n) //及时更新答案
			ans=max(f[i],ans);
	}
	printf("%d\n",ans);
	return 0;
}

         

可以欣赏一下这个超时版本


//朴素版本:    超时版本
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+1;
int n,l,r,a[maxn],f[maxn],ans=-1<<30;
int main()
{
	scanf("%d%d%d",&n,&l,&r);
	for(int i=0;i<=n;i++) scanf("%d",&a[i]);
	memset(f,0xcf,sizeof(f));f[0]=0;//由于冰冻指数可能是负数,所以一定要记得初始化
	for(int i=l;i<=n+r-1;i++)//第一步至少跳到第l格,最后一步至多跳到第n+r-1格 
	{
		for(int j=max(0,i-r);j<=i-l;j++) f[i]=max(f[i],f[j]+a[i]);
		if(i>=n) ans=max(ans,f[i]);//已经跳到对岸了再更新答案 
	}
	printf("%d",ans);
	return 0;
}

       

        

题目:选数游戏

     

思路: 

              

不同于连续的区间和,这个若干离散长度,且最大连续不超过k,和之前做法不一样。

每个点都有两种状态,被选上和未被选上,但是不能有连续超过k个被选上,那么不被选上的数应该会很少。      

     

我们设置f[i] 代表第i个点不取的最优解。状态转移:f[i]=max{f[j],sum[j+1~i-1]}(i-j<=k)向后递推,最终求解f[n+1]即可(f[j]是不被选上的,故不能加上a[j])

       
那么如何判优呢?

假设从f[a]转移到f[c]优于f[b]转移到f[c](a<b<c) 则f[a]+sum[c-1]-sum[a]>=f[b]+sum[c-1]-sum[b] 易得f[a]-sum[a]>=f[c]-sum[b]

      
故我们维护一个f[j]-sum[j]数组[i-k-1~i-1]的单调队列,遍历每个i不断取出最大值即可

      
入队新元素为i-1  所以h<=t&&f[q[t]]-suf[q[t]]<f[i-1]-suf[i-1]
过期队头和i-k-1比较  所以h<=t&&q[h]<i-k-1  取等时成立
更新f[i]  f[i]=f[q[h]]+suf[i-1]-suf[q[h]]
 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int a[N],n,k,q[N];
ll suf[N],f[N];
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)cin>>a[i],suf[i]=suf[i-1]+a[i];
	int h=1,t=0;
	for(int i=1;i<=n+1;i++){
		while(h<=t&&f[q[t]]-suf[q[t]]<f[i-1]-suf[i-1])t--;//这个一定要在最前面,因为这一步可能影响到q[h]
		q[++t]=i-1;
		while(h<=t&&q[h]<i-k-1)h++;
		f[i]=f[q[h]]+suf[i-1]-suf[q[h]];
	}
	cout<<f[n+1];
}

      

       

题目:寻找段落

        

思路:

      

注意到段落长度是个范围(还很大),只能二分来做,那么是对段落长度二分吗? 这样的话怎么对获得的最大平均值来调整段落长度呢?

     
其实我们应该对最大平均值二分,然后根据题目的这个段落能不能达到,若能达到就继续减小最大平均值mid!!!

     
操作:

首先对数组减去mid,那么只需要判断[s,t]的段落中有没有出现>=0,如果出现就说明答案至少是它,可以尝试增加mid
    

再细节一点:假如遍历到了i,那么只需要看看suf[i]-max(suf[i-T~i-S])有没有>=0,故我们要维护一个suf数组[i-T, i-S]到最大值的单调队列,从而遍历所有i

       
入队新元素为i-S  所以h<=t&&suf[q[t]]>suf[i-S] 
过期队头和i-T比较  所以h<=t&&q[h]<i-T  取等时也成立
判断suf[i]-suf[q[h]]>=0成不成立即可
      

#include <bits/stdc++.h>
using namespace std;
const int N=100010;
double l,r,mid,a[N],suf[N];
int n,S,T,q[N];
int check(double mid){
	int h=1,t=0;
	suf[0]=0;
	for(int i=1;i<=n;i++) suf[i]=suf[i-1]+a[i]-mid;//初始化前缀和数组
	for(int i=S;i<=n;i++){
		while(h<=t&&suf[q[t]]>suf[i-S])t--;//维护单调性,新元素为suf[i-S]哦
		q[++t]=i-S;//入队
		while(h<=t&&q[h]<i-T)h++;//过期的出队
		if(h<=t&&suf[i]-suf[q[h]]>=0)return 1;//判断每个[S,T]长度的段落有没有>=0
	}
	return 0;
}
int main(){
	cin>>n>>S>>T;
	for(int i=1;i<=n;i++)cin>>a[i];
	l=-100000,r=100000;
	while(r-l>1e-5){//二分精确模板
		mid=(l+r)/2;
		if(check(mid))l=mid;
		else r=mid;
	}
	printf("%.3f",mid);
}

好了,讲完了,各位观众老爷们点个赞再走吧

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

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

相关文章

Flutter有状态组件StatefulWidget生命周期

StatefulWidget是Flutter中的一个有状态的组件&#xff0c;它的生命周期相对复杂一些。下面是StatefulWidget的生命周期方法及其调用顺序&#xff1a; 1. createState(): 当StatefulWidget被插入到Widget树中时&#xff0c;会调用createState()方法来创建与之关联的State对象。…

如何有效概括一段工作经历?

问题描述&#xff1a; 如何有效概括一段工作经历&#xff1f; 解决方案&#xff1a; 1.要有效概括一段工作经历&#xff0c;可以遵循以下几个步骤&#xff1a; 确定关键信息&#xff1a;仔细审查工作经历&#xff0c;确定其中的关键信息和亮点。这可能包括你的职位、工作职责…

VR建筑仿真场景编辑软件有助于激发创作者的灵感和创造力

随着VR虚拟现实技术的不断发展和普及&#xff0c;VR虚拟场景编辑器逐渐成为了VR场景开发重要工具。它对于丰富和完善VR虚拟现实内容的创建和呈现具有重要的意义&#xff0c;为我们的工作和教学带来了许多变化和可能性。 首先&#xff0c;VR虚拟场景编辑器对于提升用户体验具有重…

C++实现查找连通域

目录 一、概述 1.1、四连通域算法 1.2、八连通域算法 1.3、种子填充法 二、代码 一、概述 图像处理中&#xff0c;查找连通域的算法是图像分割的重要方法之一。它能够将一幅图像分成若干个不重叠的区域&#xff0c;每个区域内部像素具有相似的性质&#xff0c;而不同区域…

【游戏开发算法每日一记】使用随机prime算法生成错综复杂效果的迷宫(C#和C++)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

【01】Istio-1.17 部署

1.1 部署Istio控制平面 部署方法 istioctl istio的专用管理工具&#xff0c;支持定制控制平面和数据平面通过命令行的选项支持完整的IstioOperator API命令行各选项可用于单独设置&#xff0c;以及接收包含IstioOperator自定义资源(CR)的yaml文件 Istio Operator Istio相关的自…

哪些东西可以用超声波清洗机洗?这四款超声波清洗机可别错过

自从去眼镜店老板用超声波清洗机给我清洗过眼镜之后&#xff0c;我就发现&#xff0c;其实很多智能家居都可以帮我们大大解决一些清洁上面的问题&#xff0c;不仅方便还很高效&#xff01;这种一举两得的事情不得安排上&#xff01;现在市面上超声波清洗机可以清洗的东西是越来…

【OpenCV(4)】使用opencv编写mp4格式和avi格式

在之前的文章《【摄影与图像】444&#xff0c;422&#xff0c;420&#xff0c;10bit&#xff0c;8bit&#xff0c;RGB,YCrCb,场序&#xff0c;h264编码,封装&#xff0c;码率&#xff0c;PR常用配置》 说到了视频&#xff1a; 1、一个视频里面包含了什么&#xff1f; 图像音频…

通过百度翻译API完成Java中的中英文翻译

因为要做英文文献索引分词&#xff0c;所以对于索引词汇必须得是英文&#xff0c;将表中的中文都转换成英文 这里用到百度的翻译API 首先需要注册成为百度翻译开发者&#xff1a;百度翻译开放平台 注册成为个人开发者就可以&#xff0c; 这里可以完善相关信息&#xff0c;要记…

关于C++链接的一些理解

无论是.h还是.cpp&#xff0c;都可以写声明或者实体&#xff0c;而且.h和.cpp的前面的名字相同不相同没有任何的影响 最终一系列要连接的程序中&#xff0c;必须有且只有一个源文件有main函数&#xff0c;然后从这个main函数开始运行 include的作用其实是跟define一样的&#x…

高效筛选的秘密武器:JVS智能BI的‘and’与‘or’逻辑

在这个信息爆炸的时代&#xff0c;数据被誉为新时代的黄金和石油&#xff0c;蕴含着无尽的价值和潜力。然而&#xff0c;随着数据的爆炸式增长&#xff0c;如何高效、准确地从海量数据中提取出真正有价值的信息&#xff0c;成为摆在我们面前的一大挑战。我们需要用数据筛选工具…

app软件开发多少钱?功能会影响价格吗?

随着智能手机的普及&#xff0c;app开发市场日益繁荣&#xff0c;很多人都有开发app的梦想&#xff0c;但开发一款app需要多少钱呢?功能是否会影响价格?本文将为你揭开这个谜团。 一、app开发费用的影响因素 app开发费用受到多种因素的影响&#xff0c;例如开发难度、功能复…

垂直领域对话系统架构

垂直领域对话系统是指针对特定领域或行业的需求而构建的对话系统。这种系统通常需要具备高度的专业知识和对特定领域的知识库进行深入的学习和训练&#xff0c;以便能够提供准确、高效、实用的服务。 垂直领域对话系统的构建通常包括以下步骤&#xff1a; 确定目标领域或行业…

OpenCV:图像噪点消除与滤波算法

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

飞天使-template模版相关知识

遇到报错django.template.exceptions.TemplateSyntaxError: ‘staticfiles’ is not a registered tag library. Must ROOT_URLCONF TEMPLATES [{BACKEND: django.template.backends.django.DjangoTemplates,DIRS: [os.path.join(BASE_DIR, templates)],APP_DIRS: True,OPTI…

css实现进度条

预期样式 方法一 <script setup> import { ref } from "vue"; // import ScreenLeft from "./ScreenLeft/index.vue"; const width ref("76.5%"); </script><template>Screen<div class"progress-contain">…

RT-DETR算法优化改进: 一种新颖的可扩张残差(DWR)注意力模块,加强不同尺度特征提取能力

💡💡💡本文全网首发独家改进:一种新颖的可扩张残差(DWR)注意力模块,加强不同尺度特征提取能力,创新十足,独家首发适合科研 1)代替RepC3进行使用; 2)DWR直接作为注意力进行使用; 推荐指数:五星 RT-DETR魔术师专栏介绍: https://blog.csdn.net/m0_63774211/…

Mysql-库的操作

1.创建数据库 CREATE DATABASE [IF NOT EXISTS] name name后可以加 CHARACTER SET 或者是 charsetname COLLATE collation_name &#xff08;mysql数据库不区分大小写&#xff09; 说明&#xff1a; name表示想创建的库的名字大写的表示关键字 [] 是可选项 CHARACTER SET…

linux openlab搭建web网站

网站需求&#xff1a; 1.基于域名 www.openlab.com 可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c; 1、基于 www.openlab.com/student 网站访问学生信息&#xff0c; 2、基于 www.openlab…

Chrome版本对应Selenium版本

1.获得浏览器版本号和驱动 访问 https://vikyd.github.io/download-chromium-history-version/ 2. 安装selenium pip install selenium3.141.0 -i http://pypi.mirrors.ustc.edu.cn/simple/ --trusted-host pypi.mirrors.ustc.edu.cn 3.解压chromedriver到python目录下 4.设…