【蓝桥杯】每日练习 Day11 逆序对问题和多路归并

目录

前言

超快速排序

分析

代码

小朋友排队

分析

代码

鱼塘钓鱼

分析

代码


前言

本来计划今天写五道题的,结果计划赶不上变化,谁能告诉我我的时间都去哪了。。。

今天给大家带来三道题目,两道逆序对问题,分别用归并排序和树状数组求解,一道多路归并。


超快速排序


分析

看完题目首先想到的是冒泡排序,但是显然冒泡排序不属于“超快速排序”。

但是既然题目的最终目的是排序,那就肯定离不开排序算法。

学过线性代数的同学都知道,有一个东西叫做逆序数,指的就是一组排列中逆序对的个数

逆序对能不能和本题的“交换次数”联系起来呢?主播很明确的告诉你们,最优的方案的交换次数就是逆序数。

如何证明呢?这个简单。

我们知道,在一个排列中交换两个相邻的元素,造成的影响是逆序数加一或者减一。

而逆序数的含义可以视为,存在一种方案使得每次相邻的两个元素交换,都能使得逆序数减一。

接下来的问题就是证明这种方案存不存在,请观察我下面的式子:

2, 3, 1

可以观察到前两个数字是已排序的,若要让这个排列的逆序数归零只需要交换3和1, 2和1,最终排列就变成了这样

1, 2, 3

逆序数归零了,并且我们每次交换操作造成的影响都是逆序数减一

所以这种方案存在,具有充分性

观察原排列,可以发现原排列可以分为两部分,即:2, 3 | 1,而每一部分内部都是排序过的。

观察上方的排列,有没有想起一个排序算法,没错,那么算法就是归并排序

我们都知道归并排序是可以求逆序对数的,接下来主播就以自己的理解来解释归并排序为什么能够求逆序对数。

首先,我们将一个排列的逆序对视为一个集合S

随后,我们将排列分为两个区间,对集合进行划分,划分为区间内的逆序对和区间间的逆序对。

至于为什么可以划分很好证明,只需要证明三个子集没有包含关系即可,通过反证法很好证明。

那么整体的逆序对数就等于区间内的逆序对数 + 区间间的逆序对数。(容斥原理)

而归并排序就是利用这种思想,先消除区间内的逆序对,再消除区间间的逆序对,来达到计算逆序对数的效果。

而我们知道归并排序处理的每个区间都是排序后的两部分,所以根据上面的充分性,消除这样的区间的逆序对数的交换次数就是逆序对数。

所以问题就转化成了归并排序求逆序对数。


代码

#include <iostream>
using namespace std;
typedef long long LL;
const int N = 500010;
int n;
int a[N],tmp[N];
LL merge_sort (int l,int r) {if (l == r) return 0;int mid = l + r >> 1;LL ans = merge_sort (l,mid) + merge_sort (mid + 1,r);int i = l,j = mid + 1,k = 0;while (i <= mid && j <= r) {if (a[i] <= a[j]) tmp[k++] = a[i++];else {tmp[k++] = a[j++];ans += mid - i + 1;}}while (i <= mid) tmp[k++] = a[i++];while (j <= r) tmp[k++] = a[j++];for (int i = l,j = 0;i <= r;i++,j++) a[i] = tmp[j];return ans;
}
int main () {while (cin >> n,n) {for (int i = 1;i <= n;i++) cin >> a[i];cout << merge_sort (1,n) << endl;}return 0;
}

小朋友排队


分析

前面我们证明了逆序对数就是至少交换次数,但是这道题有写不一样,我们需要统计交换双方需要交换的次数那显然就不只是逆序对数了。

主播刚开始以为答案就是逆序对数乘以二,可是后来发现这个想法是错误的,因为每个元素的逆序对数只能代表他“主动”与别人交换的次数,并不能代表这个元素交换的次数,观察下方案例。

3, 2, 1

通过观察可以发现要想排序可以发现1要交换两次,3要交换两次,2也需要交换两次。

要讲明白一个知识点,主播需要先引入一个概念:

顺序对(主播自己起的名字,也不知道对不对),与逆序对相反,不过区别是顺序对指的是在这个元素之后小于这个元素的个数。

反过来看,对于后面的元素来说,可以将顺序对拆分成n部分,而其中的每一部分就是对于该元素的一个逆序对。

而后面的元素要想消除自己的逆序对就一定要与当前元素进行交换,我们将这种行为视为消除该元素的顺序对。

这样就同时统计了每个元素主动交换和被动交换的所有情况,因为最开始行为是区间划分,所以也无需判重

主播这次是用树状数组实现,树状数组的写法很暴力,就是对每个数字统计在他前面且比他大的数字。


代码

// 树状数组求逆序对和顺序对
#include<iostream>
#include<cstring>
/*#define y second
#define x first*/
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 100010, P = 1000010;
int n;
int h[N];
int tree[P];
int st[N];
int lowbit(int x)
{return x & -x;
}void insert(int i, int x)
{if(i >= P) return;tree[i] += x;insert(i + lowbit(i), x);
}int find(int x)
{if(x == 0) return tree[0];return tree[x] + find(x - lowbit(x));
}int main()
{scanf("%d", &n);for(int i = 1; i <= n;h[i]++, i++) scanf("%d", h + i);for(int i = 1; i <= n; i++){st[i] += i - 1 - find(h[i]); //找大于当前数字的insert(h[i], 1);}memset(tree, 0, sizeof(tree));for(int i = n; i >= 1; i--){st[i] += find(h[i] - 1); // 小于当前数字的insert(h[i], 1);}LL l = 0;for(int i = 1; i <= n; i++)l += ((st[i] + 1) * (LL)st[i]) / 2;printf("%lld", l);return 0;
}

鱼塘钓鱼


分析

首先想到可以搜索,但是数据量很大,而且状态也不好表示,所以先排除搜索。

首先先观察整体,可以发现每次换鱼塘只会消耗时间而不会带来重复收益,所以贪心思路是至多到达一次此鱼塘,即:一条路走下去,不要反复横跳。(这种找最优解的题一般是先分析整体看有没有明显重复的部分,随后就可以根据这些重复的部分确定贪心思路)。

随后发现了在哪个位置钓鱼的收益与时间无关只和次数有关,接下来我们来思考一下能否将交换位置的时间剥离出来。

显然是可以的,随后我们可以枚举终点位置,即:每次只在1 ~ x的鱼塘内钓鱼。

接下来就变成了多个链表求最优和的问题。

可以发现每一个位置都是一个等差数列,并且考虑到有多个位置,每个位置地位相当,我们考虑使用多路归并算法。

有的人可能没有听说过这个算法,但其实这个算法很简单,合并两个有序数组用的就是多路归并算法。

随后根据等差数列的性质,最大的数字一定会出现在最表层,所以我们用堆来查找出外层的最大值依次增加即可。


代码

// 贪心 + 多路归并,枚举1 ~ n,每次多路归并查找
// 时间复杂度: n * t * logN, 时间肯定够。
#include<iostream>
#include<cstring>
#include<queue>
#define s second
#define f first
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int n, T, mx;
int a[N], b[N], t[N], st[N];
priority_queue<PII> pq;int main()
{scanf("%d", &n);for(int i = 0; i < n; i++) scanf("%d", a + i);for(int i = 0; i < n; i++) scanf("%d", b + i);for(int i = 1; i < n; i++) scanf("%d", t + i);scanf("%d", &T);for(int i = 0; i < n; i++) //枚举从0到i{int s = 0, l = 0;pq = priority_queue<PII>(); //重构。memset(st, 0, sizeof(st)); for(int j = 0; j <= i; j++){pq.push({a[j], j}); s += t[j]; //第一部分贪心的时间}while(s < T){PII x = pq.top(); pq.pop();l += max(0, x.f); st[x.s]++; pq.push({a[x.s] - st[x.s] * b[x.s], x.s});s++;}mx = max(mx, l);}    printf("%d", mx);return 0;
}

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

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

相关文章

OpenCV 图像基本操作

之前几篇文章介绍了OpenCV的一些模块概念,并没有细说每个模块具体的方法和使用。接下来就会详细介绍每个模块模块包含的方法和使用。 本文将详细介绍图像的四种基本操作:访问和修改像素值、图像 ROI (Region of Interest) 操作、图像通道分离与合并、以及图像的缩放、旋转、…

酷淘商场项目【从零到一详解】Web端

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

Gemini 2.0 Flash 图片去水印测试

Gemini 2.0 Flash 模型不仅会生成包含名人和受版权保护角色的图像&#xff0c;还会去除现有照片中的水印。 据 X 和 Reddit 上的多位用户指出&#xff0c;Gemini 2.0 Flash 模型不仅会去除水印&#xff0c;还会尝试填补因水印删除而产生的空白区域。其他基于人工智能的工具也能…

STM32学习笔记之keil使用记录

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

MQTT消息服务器新玩法:EMQX结合内网穿透的实战配置指南

文章目录 前言1. 查看EMQX本地WS端口2. Linux安装Cpolar工具3. 配置WS公网连接地址4. WS公网地址连接测试5. 配置WSS公网连接地址6. WSS公网地址连接测试 前言 随着物联网技术的不断发展&#xff0c;MQTT作为一种轻量级的消息发布/订阅协议&#xff0c;在物联网通信中扮演着越…

编程题记录3

九宫幻方 题目链接&#xff1a;https://www.lanqiao.cn/problems/100/learning/?page1&first_category_id1&second_category_id3&tags%E7%9C%81%E8%B5%9B&tag_relationintersection 先旋转、镜像得到所有的情况&#xff0c;可以发现情况是可以暴力得出的。…

电机控制常见面试问题(十八)

文章目录 一.电机控制高级拓扑结构1.LLC 二.谈谈电压器饱和后果三.电压器绕组连接方式的影响四.有源逆变的条件 一.电机控制高级拓扑结构 1.LLC LLC是什么&#xff1f;—— 一个会"变魔术"的电源盒子 想象你有一个魔法盒子&#xff0c;能把电池的电压变大或变小&…

C#设计模式快速回顾

知识点来源&#xff1a;人间自有韬哥在&#xff0c;豆包 目录 一、七大原则1. 单一职责原则 (Single Responsibility Principle)2. 开放封闭原则 (Open-Closed Principle)3. 里氏替换原则 (Liskov Substitution Principle)4. 接口隔离原则 (Interface Segregation Principle)5…

汇编语言高级编程技巧:从基础到进阶

前言 汇编语言作为底层编程语言&#xff0c;直接操作硬件&#xff0c;执行效率高&#xff0c;但编写复杂逻辑时往往显得繁琐。通过使用汇编伪指令和宏&#xff0c;我们可以实现类似于高级语言的结构&#xff0c;如条件判断、循环、结构体和函数等&#xff0c;从而提升代码的可读…

XSS跨站脚本攻击漏洞(Cross Site Scripting)

前提概要 本文章主要用于分享XSS跨站脚本攻击漏洞基础学习&#xff0c;以下是对XSS跨站脚本攻击漏洞的一些个人解析&#xff0c;请大家结合参考其他文章中的相关信息进行归纳和补充。 XSS跨站脚本攻击漏洞描述 跨站脚本攻击&#xff08;XSS&#xff09;漏洞是一种常见且危害较…

2、pytest核心功能(进阶用法)

目录 1、标记&#xff08;Markers&#xff09;&#xff1a; 自定义插件 内置标记 2、夹具&#xff08;Fixtures&#xff09;&#xff1a; 夹具得用法 夹具作用域 3、钩子&#xff08;hook&#xff09;&#xff1a; 这篇是最重要的 测试文件中需要用到的 总的来说 有以下…

恒流源电路深度解析:各类架构的优缺点与应用场景

点击下面图片&#xff0c;为您提供全新的嵌入式学习路线 文章目录 ①. 单晶体管恒流源②. NPNPNP组合恒流源③. 双晶体管恒流源④. 镜像电流源⑤. 比例电流源⑥. 微电流源⑦. 加射极输出的镜像电流源⑧. 威尔逊电流源⑨.综合对比表⑩.选型建议 恒流源是电子电路中的基础模块&…

研究生入学前文献翻译训练

文献翻译 人工智能《Meta - Learning with Memory - Augmented Neural Networks》one-shot learning:Neural Turing Machines,NTMs《Model - Agnostic Meta - Learning for Fast Adaptation of Deep Networks》Meta - learninggradient stepsfinetune《Attention Is All You …

在IDEA中快速注释所有console.log

在IDEA中快速注释所有console.log 在前端IDEA中&#xff0c;快速注释所有console.log语句可以通过以下步骤实现2&#xff1a; 打开要修改的文件。使用快捷键CtrlF打开搜索框。点击打开使用正则搜索的开关或者通过AltR快捷键来打开。在搜索框输入[]*console.log[]*&#xff0c;…

#C8# UVM中的factory机制 #S8.2.1# factory 机制重载法则

factory机制最伟大的地方在于其具有重载功能。重载并不是factory机制的发明,前面已经介绍过的所有面向对象的语言都支持函数/任务重载,另外,SystemVerilog还额外支持对约束的重载。只是factory机制的重载与这些重载都不一样。 一 问题引出 以8.1.1节的代码清单8-1和代码清…

macOS 15 通过 MacPorts 安装 PHP 7 构建错误找不到符号在 dns.o 中解决方法

构建遇到的问题如下&#xff1a; "_res_9_dn_expand", referenced from:_php_parserr in dns.o_php_parserr in dns.o_php_parserr in dns.o_php_parserr in dns.o_php_parserr in dns.o_php_parserr in dns.o_zif_dns_get_mx in dns.o..."_res_9_dn_skipname&…

MDK优化等级对浮点运算效率的影响

MDK优化等级&#xff1a;Default模式 和 O0模式 在支持浮点运算的MCU&#xff08;如STM32的Cortex-M4或Cortex-M7系列&#xff09;上&#xff0c;执行浮点运算的算法时&#xff0c;MDK编译器的优化等级配置为 default模式&#xff08;通常是O1或O2&#xff09;和 O0模式&#…

嵌入式学习第二十八天--栈

栈的基本代码 栈是限定仅在表尾进行插入和删除操作的线性表。 先进后出、后进先出 栈顶:允许操作的一端 栈底:不允许操作的一端 入栈&#xff0c;出栈。 顺序栈 链式栈 302\5 1.创建 CreateSeqStack 2.销毁 DestroySeqStack 3.判断是否为空栈 IsEmptySeqStack 4.判断是否为满…

MySQL中怎么分析性能?

MySQL中主要有4种方式可以分析数据库性能&#xff0c;分别是慢查询日志&#xff0c;profile&#xff0c;Com_xxx和explain。 慢查询日志 先用下面命令查询慢查询日志是否开启&#xff0c; show variables like slow_query_log;# 一般默认都是以下结果 ---------------------…

大模型在支气管哮喘手术全流程风险预测与治疗方案制定中的应用研究

目录 一、引言 1.1 研究背景与意义 1.2 研究目标与方法 1.3 研究创新点 二、支气管哮喘概述 2.1 定义与发病机制 2.2 分类与临床表现 2.3 诊断标准与方法 三、大模型技术原理与应用现状 3.1 大模型的基本原理 3.2 在医疗领域的应用案例分析 3.3 适用于支气管哮喘预…