NO.64十六屆藍橋杯備戰|基礎算法-簡單貪心|貨倉選址|最大子段和|紀念品分組|排座椅|矩陣消除(C++)

貪?算法是兩極分化很嚴重的算法。簡單的問題會讓你覺得理所應當,難?點的問題會讓你懷疑??

什么是貪?算法?

貪?算法,或者說是貪?策略:企圖?局部最優找出全局最優。

  1. 把解決問題的過程分成若?步;
  2. 解決每?步時,都選擇"當前看起來最優的"解法;
  3. "希望"得到全局的最優解。
貪?算法的特點
  1. 對于?多數題?,貪?策略的提出并不是很難,難的是證明它是正確的。因為貪?算法相較于暴?枚舉,每?步并不是把所有情況都考慮進去,?是只考慮當前看起來最優的情況。但是,局部最優并不等于全局最優,所以我們必須要能嚴謹的證明我們的貪?策略是正確的。
    ?般證明策略有:反證法,數學歸納法,交換論證法等等。
  2. 當問題的場景不同時,貪?的策略也會不同。因此,貪?策略的提出是沒有固定的套路和模板的。我們后?講的題?雖然分類,但是?家會發現具體的策略還是相差很?。因此,不要妄想做?道貪?題?就能遇到?個會?個。有可能做完50道貪?題?之后,第51道還是沒有任何思路。
如何學習貪??

先有?個認知:做了??道貪?的題?,遇到?個新的?沒有思路,這時很正常的現象,把?態放平。

  1. 前期學習的時候,重點放在各種各樣的策略上,把各種策略當成經驗來吸收;
  2. 在平常學習的時候,我們盡可能的證明?下這個貪?策略是否正確,這樣有利于培養我們嚴謹的思維。但是在?賽中,能想出來?個策略就已經不錯了,如果再花費?量的時間去證明,有點得不償失。這個時候,如果根據貪?策略想出來的若?個邊界情況都能過的話,就可以嘗試去寫代碼了。
P10452 貨倉選址 - 洛谷

將所有的商店按照「從?到?」的順序「排序」,把貨倉建在中位數處,可以使得貨倉到每家商店的距離之和最?:

  • 如果n是奇數,貨倉建在a[(n + 1)/2] 位置處;
  • 如果n是偶數,貨倉建在a[n/2] ~ a[n/2 + 1]之間都是可以的
#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int N = 1e5+10;int n;
int a[N];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];sort(a+1, a+1+n);LL ret = 0;for (int i = 1; i <= n; i++){//中間位置的下標是(1+n)/2ret += abs(a[i] - a[(1+n) / 2]);}cout << ret << endl;return 0;
}

∣ a ? x ∣ + ∣ b ? x ∣ ≥ ∣ a ? b ∣ |a-x|+|b-x| \ge |a-b| a?x+b?xa?b
![[Pasted image 20250404104208.png]]

當x處于兩者的中間位置時,左式取得最小值
形如:
s u m = ∑ i = 1 n ∣ a [ i ] ? x ∣ = ∣ a [ 1 ] ? x ∣ + ∣ a [ 2 ] ? x ∣ + ? + ∣ a [ n ] ? x ∣ sum = \sum^{n}_{i=1}|a[i]-x|=|a[1]-x|+|a[2]-x|+\dots+|a[n]-x| sum=i=1n?a[i]?x=a[1]?x+a[2]?x+?+a[n]?x

  • 當x 取到n 個數的中位數時,和最?;
  • 最?和為:
    ( a [ n ] ? a [ 1 ] ) + ( a [ n ? 1 ] ? a [ 2 ] ) + . . . + ( a [ n + 1 ? n / 2 ] ? a [ n / 2 ] ) (a[n] - a[1]) + (a[n - 1] - a[2]) + ... + (a[n + 1 - n/2] - a[n/2]) (a[n]?a[1])+(a[n?1]?a[2])+...+(a[n+1?n/2]?a[n/2])
#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int N = 1e5+10;int n;
int a[N];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];sort(a+1, a+1+n);LL ret = 0;for (int i = 1; i <= n/2; i++){ret += abs(a[i] - a[n+1-i]);      }cout << ret << endl;return 0;
}
P1115 最大子段和 - 洛谷

貪?想法:從前往后累加,我們會遇到下?兩種情況:

  • ?前的累加和>=0:那么當前累加和還會對后續的累加和做出貢獻,那我們就繼續向后累加,然后更新結果;
  • ?前的累加和<0:對后續的累加和做不了?點貢獻,直接?膽舍棄計算過的這?段,把累加和重置為0,然后繼續向后累加。
    這樣我們在掃描整個數組?遍之后,就能更新出最??段和。
    ![[Pasted image 20250404143727.png]]

在累加的過程中算出?段區間和sum[a,b]<0 ,如果不舍棄這?段,那么[a,b]段之間就會存在?點,「以某個位置為起點」就會「更優」,分為下?兩種情況

  1. 在ab段存在?個點c ,從這個位置開始,「越過b 」的累加和?從a 開始的累加和更優:
    ?「反證法」證明這種情況不存在。
    如果存在這?點,那么:sum[c, b] > sum[a, b] ,這樣才能保證向后加的時候更優。
    但這是「不可能」的。如果sum[c, b] > sum[a, b] ,那么sum[a, c-1]<0,這與我們的貪?策略?盾。
    因為我們貪?策略向后加的時候,只要不?于0,就會?直加下去。如果[a, c-1]段?于0,就
    會在c點之前停?,不會累加到b。
    因此區間內不存在?點,在計算?數組和時,在「越過b 」的情況下,能?從a 開始更優。
  2. 在ab段存在?個點c ,從這個位置開始,「不越過b 」的累加和?從a 開始的累加和更優:
    也可以?「反證法」證明這種情況不存在。
    如果存在這?點,那么:sum[c, k] > sum[a, k]
    但這是不可能的。如果sum[c, k] > sum[a, k],那么sum[a, c - 1] < 0 ,這與我們的貪?策略?盾。
    因此區間內不存在?點,在計算?數組和時,在「不越過b 」的情況下,能?從a 開始更優。
    綜上所述,我們可以?膽舍棄這?段,重新開始。
#include <bits/stdc++.h>
using namespace std;const int N = 2e5 + 10;typedef long long LL;int n;
LL a[N];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];LL sum = 0, ret = -1e6;for (int i = 1; i <= n; i++){sum += a[i];ret = max(ret, sum);if (sum < 0) sum = 0;}cout << ret << endl;return 0;
}
P1094 [NOIP 2007 普及組] 紀念品分組 - 洛谷

先將所有的紀念品排序,每次拿出當前的最?值x 與最?值y :

  • 如果x + y ≤ w :就把這兩個放在?起;
  • 如果x + y > w:說明此時最?的和誰都湊不到?起,y單獨分組,x繼續留下在進?下?次判斷。
    直到所有的物品都按照上述規則分配之后,得到的組數就是最優解

可以?「交換論證法」證明貪?解就是最優解:
對于區間[ai......aj],如果存在最優解,但是aiaj的分配?式與我們貪?解的分配?式不?樣,那么就會有以下?種情況:

  1. a[i] + a[j] > w時:
  • 貪?解會把a[j]單獨分組,a[i]留待下次考慮;
  • 最優解也必定會把a[j]單獨分組,因為沒有更?的值與a[j]組合。
    此時貪?解與最優解?致。
  1. a[i] + a[j] ≤ w時:
  • 貪?解會把兩者組合分在?個組??;
  • 最優解可能有以下?種情況:
    • a[j]單獨?組:
      • 如果a[i]也單獨?組的話,最優解還不如貪?解分的組少,?盾;
      • 如果a[i]和另?個a[k]?組的話,我們可以把a[k]a[j]交換,此時并不影響結果,和貪?解?致。
    • a[j]a[k]?組:
      • 如果a[i]單獨?組的話,交換a[i]a[k],此時并不影響最終結果,和貪?解?致;
      • 如果a[i]a[l]?組的話,交換a[i]a[k],此時變成(a[i]+a[j]),(a[l]+a[k]),其中a[l]+a[k]<=a[j]+a[k]<=w,不影響最終結果,和貪?解?致。
        綜上所述,我們可以通過不斷的「調整」,使的最優解在「不改變其最優性」的前提下,變得和貪?解?致。那我們的貪?策略就等價于最優策略。
#include <bits/stdc++.h>
using namespace std;const int N = 3e4 + 10;int w, n;
int a[N];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> w >> n;for (int i = 1; i <= n; i++) cin >> a[i];sort(a+1, a+1+n);int l = 1, r = n, ret = 0;while (l <= r){if(a[l] + a[r] <= w) l++, r--;else r--;ret++;}cout << ret << endl;return 0;
}
P1056 [NOIP 2008 普及組] 排座椅 - 洛谷

由題意可得,我們會發現?些性質:

  • 設置橫向通道的時候,并「不影響」左右相鄰的同學;
  • 設置縱向通道的時候,并「不影響」上下相鄰的同學。
    因此我們可以「分開」處理橫向通道和縱向通道。
    處理橫向通道(縱向同理,就不多贅述):
  • 收集每??如果放上通道之后,會解決多少個交頭接?的同學;
  • 對收集的信息「從?到?」排序,選最?的k ?就是最優結果。
#include <bits/stdc++.h>
using namespace std;const int N = 1010;struct node
{int index;int cnt;
}row[N], col[N];int m, n, k, l, d;//按cnt從大到小
bool cmp1(node& x, node& y)
{return x.cnt > y.cnt;
}
//按index從小到大
bool cmp2(node& x, node& y)
{return x.index < y.index;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> m >> n >> k >> l >> d;//初始化結構體數組for (int i = 1; i <= m; i++) row[i].index = i;for (int i = 1; i <= n; i++) col[i].index = i;while(d--){int x, y, p, q; cin >> x >> y >> p >> q;if (x == p) col[min(y, q)].cnt++;else row[min(x, p)].cnt++;}//對兩個數組按照cnt從大到小排序sort(row+1, row+1+m, cmp1);sort(col+1, col+1+n, cmp1);//對row數組,前k個元素,按照下標從小到大排序sort(row+1, row+1+k, cmp2);//對col數組,前l個元素,按照下標從小到大排序sort(col+1, col+1+l, cmp2);for (int i = 1; i <= k; i++){cout << row[i].index << " ";}cout << endl;for (int i = 1; i <= l; i++){cout << col[i].index << " ";}cout << endl;return 0;
}
矩陣消除游戲

最優解是先暴?枚舉所有?的選法,在?的選擇都確定之后,再去貪?的處理列

#include <bits/stdc++.h>
using namespace std;const int N = 20;int n, m, k;
int a[N][N];
int col[N]; //統計列和//統計x的二進制中1的個數
int calc(int x)
{int ret = 0;while (x){ret++;x -= x & -x;}return ret;
}//從大到小排序
bool cmp(int a, int b)
{return a > b;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m >> k;for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)cin >> a[i][j];int ret = 0;//暴力枚舉行所有選法for (int st = 0; st < (1 << n); st++){int cnt = calc(st);if (cnt > k) continue; //不合法memset(col, 0, sizeof col);int sum = 0; //記錄當前選法的和for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){if ((st >> i) & 1) sum += a[i][j];else col[j] += a[i][j];}}//處理列sort(col, col + m, cmp);//選k - cnt列for (int j = 0; j < min(k - cnt, m); j++) sum += col[j];ret = max(ret, sum);}cout << ret << endl;return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/pingmian/75516.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75516.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75516.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux(十二)信號

今天我們就要來一起學習信號啦&#xff01;&#xff01;&#xff01;還記得小編在之前的文章中說過的ctrlc嗎&#xff1f;之前小編沒有詳細介紹過&#xff0c;現在我們就要來學習啦&#xff01;&#xff01;&#xff01; 一、信號的基本介紹 首先&#xff0c;小編帶領大家先一…

Dify開發實戰-自制插件 和安裝python3最新版本 記錄版本 后續會持續更新

自定義插件 Dify 插件腳手架工具Python 環境&#xff0c;版本號 ≥ 3.12 安裝Python 一 進入官網 https://www.python.org/downloads/windows/ 點擊下載 二、安裝python&#xff08;本文中有借鑒其他圖片 所以圖片展示python版本可能不一致 請忽略&#xff09; 1.雙擊打開py…

Docker安裝、配置Redis

1.如果沒有docker-compose.yml文件的話&#xff0c;先創建docker-compose.yml 配置文件一般長這個樣子 version: 3services:redis:image: redis:latestcontainer_name: redisports:- "6379:6379"command: redis-server --requirepass "123456"restart: a…

Parasoft C++Test軟件單元測試_操作指南

系列文章目錄 Parasoft C++Test軟件靜態分析:操作指南(編碼規范、質量度量)、常見問題及處理 Parasoft C++Test軟件單元測試:操作指南、實例講解、常見問題及處理 Parasoft C++Test軟件集成測試:操作指南、實例講解、常見問題及處理 進階擴展:自動生成靜態分析文檔、自動…

二級索引詳解

二級索引詳解 二級索引(Secondary Index)是數據庫系統中除主鍵索引外的附加索引結構,用于加速基于非主鍵列的查詢操作。以下是關于二級索引的全面解析: 一、核心概念 特性主鍵索引 (Primary Index)二級索引 (Secondary Index)唯一性必須唯一可以唯一或非唯一數量每表只有…

Python_level1_字符串_11

目錄 一、基本概念 二、字符串基本操作&#xff1a;【索引、切片、遍歷】 1.字符串與列表&#xff08;相同&#xff09; 1&#xff09;索引&#xff08;從0開始&#xff09;(可以獲取某一個/某幾個連續的字符) 2&#xff09;切片 [xx:xx] 與 列表 語法規則一樣 [起…

Axure數據可視化科技感大屏設計資料——賦能多領域,展示無限價值

可視化大屏如何高效、直觀地展示數據&#xff0c;并將其轉化為有價值的決策依據&#xff0c;成為了許多企業和組織面臨的共同挑戰。Axure大屏可視化模板&#xff0c;作為一款強大的數據展示工具&#xff0c;正在以其出色的交互性和可定制性&#xff0c;賦能多個領域&#xff0c…

MySQL 性能調優:數據庫的極限運動訓練

就像運動員需要不斷訓練才能突破極限&#xff0c;數據庫也需要各種調優才能跑得更快…讓我們一起給 MySQL 安排一套專業的"健身計劃"&#xff01; 什么是 MySQL 性能調優&#xff1f;&#x1f914; MySQL 性能調優是指通過各種配置優化、結構調整和查詢改進&#x…

4.5/Q1,GBD數據庫最新文章解讀

文章題目&#xff1a;Emerging trends and cross-country health inequalities in congenital birth defects: insights from the GBD 2021 study DOI&#xff1a;10.1186/s12939-025-02412-7 中文標題&#xff1a;先天性出生缺陷的新趨勢和跨國健康不平等&#xff1a;GBD 202…

基于DeepSeek、ChatGPT支持下的地質災害風險評估、易發性分析、信息化建庫及災后重建

前言&#xff1a; 地質災害是指全球地殼自然地質演化過程中&#xff0c;由于地球內動力、外動力或者人為地質動力作用下導致的自然地質和人類的自然災害突發事件。在降水、地震等自然誘因的作用下&#xff0c;地質災害在全球范圍內頻繁發生。我國不僅常見滑坡災害&#xff0c;還…

Linux | 安裝超級終端串口軟件連接i.MX6ULL開發板(8)

01 它的安裝步驟也非常簡單,安裝語言選擇中文簡體,點擊確定,如下圖所示。 點擊下一步,如下圖所示。 02

藍橋杯15屆 寶石組合

問題描述 在一個神秘的森林里&#xff0c;住著一個小精靈名叫小藍。有一天&#xff0c;他偶然發現了一個隱藏在樹洞里的寶藏&#xff0c;里面裝滿了閃爍著美麗光芒的寶石。這些寶石都有著不同的顏色和形狀&#xff0c;但最引人注目的是它們各自獨特的 “閃亮度” 屬性。每顆寶…

Lua:第1-4部分 語言基礎

1 Lua語言入門 1.1 程序段 我們將 Lua 語言執行的每一段代碼&#xff08;例如&#xff0c;一個文件或交互模式下的一行&#xff09;稱為一個程序段 &#xff08; Chunk &#xff09; &#xff0c;即一組命令或表達式組成的序列 。 1.2 一些詞法規范 Lua 語言中的標識符&#…

CTF類題目復現總結-hashcat 1

一、題目地址 https://buuoj.cn/challenges#hashcat二、復現步驟 1、下載附件&#xff0c;解壓得到What kind of document is this_文件&#xff1b; 2、用010 Editor打開What kind of document is this_文件&#xff0c;發現是office文件&#xff1b; 3、將后綴名改為ppt時…

手機歸屬地查詢Api接口,數據準確可靠

手機歸屬地查詢是一項非常實用的功能&#xff0c;它可以幫助我們快速了解一個手機號碼的所屬地區、區號、郵政編碼等信息。在互聯網時代&#xff0c;隨著大數據和人工智能技術的發展&#xff0c;手機歸屬地查詢的API接口也變得越來越普及和便捷。 在本文中&#xff0c;我們將介…

orangepi zero燒錄及SSH聯網

下載對應版本的armbian鏡像 armbian的默認用戶root&#xff0c;默認密碼&#xff1a;1234 下載燒錄工具win32diskimager https://sourceforge.net/projects/win32diskimager/files/Archive/ 插入16G以上TF卡&#xff0c;使用win32diskimager燒錄armbian鏡像 燒錄完畢后用l…

為什么有的深度學習訓練,有訓練集、驗證集、測試集3個劃分,有的只是劃分訓練集和測試集?

在機器學習和深度學習中&#xff0c;數據集的劃分方式取決于任務需求、數據量以及模型開發流程的嚴謹性。 1. 三者劃分&#xff1a;訓練集、驗證集、測試集 目的 訓練集&#xff08;Training Set&#xff09;&#xff1a;用于模型參數的直接訓練。驗證集&#xff08;Validati…

Linux驅動開發 塊設備

目錄 序言 1.塊設備結構 分區(gendisk) 請求(request) 請求隊列 1. 多隊列架構 2. 默認限制與擴展 bio 2.塊設備的使用 頭文件與宏定義 blk-mq 相關結構和操作 塊設備操作函數 模塊初始化函數 模塊退出函數 3.總結 序言 塊設備&#xff08;如硬盤、虛擬盤&#x…

ResNet改進(14):添加 EMA注意力機制提升跨空間學習效率

本專欄代碼均經過測試,可以直接替換項目中的模型,一鍵運行! 采用最新的即插即用模塊,有效漲點!! 1.EMA注意力機制 EMA(Efficient Multi-scale Attention)注意力機制是一種創新的注意力設計,能夠有效提升模型在跨空間學習任務中的表現。以下是對該機制的詳細解析: EM…

計算機硬件——CPU 主要參數

什么是 CPU &#xff1f; CPU 的英文全稱是 Central Processing Unit&#xff0c;即中央處理器。CPU 的內部結構可分為控制單元、邏輯單元和存儲單元三大部分。CPU 的性能大致上反映出了它所配置的微機的性能&#xff0c;因此 CPU 的性能指標十分重要。 CPU 的主要參數 CPU …