【藍橋杯】每日練習 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.pswp.cn/web/73239.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73239.shtml
英文地址,請注明出處:http://en.pswp.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 適用于支氣管哮喘預…