NO.66十六屆藍橋杯備戰|基礎算法-貪心-區間問題|凌亂的yyy|Rader Installation|Sunscreen|牛欄預定(C++)

區間問題是另?種?較經典的貪?問題。題??對的對象是?個?個的區間,讓我們在每個區間上做出取舍。
這種題?的解決?式?般就是按照區間的左端點或者是右端點排序,然后在排序之后的區間上,根據題?要求,制定出相應的貪?策略,進?得到最優解。
具體是根據左端點還是右端點排序?升序還是降序??般是假設?種排序?式,并且制定貪?策略,當沒有明顯的反例時,就可以嘗試去寫代碼。

P1803 凌亂的yyy / 線段覆蓋 - 洛谷

按照區間左端點從?到?排序,當兩個區間「重疊」的時候,我們必須要舍棄?個。為了能夠「在移除某個區間后,保留更多的區間」,我們應該把「區間范圍較?」的區間移除。
因此以第?個區間為基準,遍歷所有的區間:

  • 如果重疊,選擇「最?的右端點」作為新的基準;
  • 如果不重疊,那么我們就能多選?個區間,以「新區間為基準」繼續向后遍歷。

可以?「交換論證法」證明我們的貪?策略是最優解:
在從前往后掃描的過程中,當貪?解和最優解第?次出現不同決策時,關于兩個區間a,b(其中a在左,b在右)的取舍,有下?兩種情況:

  1. a, b兩個區間不重疊:
  • 貪?解會將a 區間保留,然后以b 區間為基準,繼續向后對?別的區間;
  • 最優解的選擇有下??種情況:
    a. 舍棄?個區間,那么必定不如貪?解,?盾。
    b. 以a區間為基準,向后對?。那更夸張了,我們已經按照區間左端點從?到?排好序了,如果a,b不重疊,那么a與后?的所有區間都不重疊,?a作為基準沒有?點意義。還會選出與b重疊的區間。
    綜上,如果「不重疊」的話,貪?解和最優解的決策應該是「?致」的。
  1. a, b 兩個區間重疊,那么?論什么解,都需要「舍棄」?個區間:
  • 貪?解會保留兩者「右端點較?」的區間,舍棄「右端點較?」的區間;
  • 最優解的選擇就是,保留「右端點較?」的區間,舍棄「右端點較?」的區間。
    如果第?種決策能在此基礎上得到最優解,那么我們把「右端點較?」區間換成「右端點較?」的區間是不受影響的。
    因為「較?區間」都和后續選擇的區間「沒有重疊」,這個較?的區間也必定「沒有重疊」。因此,最優解可以調整成貪?解。
#include <bits/stdc++.h>
using namespace std;const int N = 1e6 + 10;int n;
struct node
{int l, r;
}a[N];bool cmp(node& x, node& y)
{return x.l < y.l;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n;for (int i = 1; i <= n; i++) cin >> a[i].l >> a[i].r;sort(a+1, a+1+n, cmp);int ret = 1;int r = a[1].r; //以第一個區間為基準for (int i = 2; i <= n; i++){int left = a[i].l, right = a[i].r;if (left < r) //有重疊{r = min(r, right);}else{ret++;r = right;}}cout << ret << endl;return 0;
}
UVA1193 Radar Installation - 洛谷

如圖所?,當?個島嶼的「坐標」已知,其實可以計算出:當雷達放在x軸的「哪段區間」時,可以覆蓋到這個島嶼
![[Pasted image 20250405192831.png]]

根據「勾股定理」得:ax的?度為 l = d 2 ? y 2 l=\sqrt{ d^{2}-y^2 } l=d2?y2 ?,那么雷達所處的范圍就是 [ x ? l , x + l ] [x-l,x+l] [x?l,x+l]。因此,針對每?個島嶼,我們都可以算出?個「能夠覆蓋它的區間」。
原問題就變成給定?些區間,所有互相重疊的區間?共有多少組。
按照區間「左端點從?到?」排序,當兩個區間「重疊」的時候,為了后?能夠「盡可能多的選出互相重疊的區間」,我們應該把「區間范圍較?」的區間移除,因為選擇較?區間會造成選出來的區間「不是互相重疊」的。
因此以第?個區間為基準,遍歷所有的區間:

  • 如果重疊,選擇「最?的右端點」作為新的基準;
  • 如果不重疊,那么我們就能多選?個區間,以「新區間為基準」繼續向后遍歷。
    可以?「反證法」證明,所有區間按照按照「左端點」排序之后,「互相重疊的區間」都是「相鄰」的:
    假設所有區間按照左端點排序之后,存在互相重疊的區間,它們是不相鄰的。也就是存在a,b,c,d四個區間,其中a,b,d互相重疊,但是a,b,c與它們三個不是互相重疊。
    設a, b, d區間重疊部分的范圍是[x, y],那么c 的位置有兩種情況:
  • c 在[x, y]的左側,與實際不符:
    因為如果c在左側,?要與a,b不是互相重疊,那么c的右端點必須要?于b的左端點,那就與所有線段按照左端點排序不符;
  • c 在[x, y]的右側,也與實際不符:
    因為如果c在右側,?要與a,b不是互相重疊,那么c的左端點必須要?于a,b的右端點的最?值;?因為d與a,b互相重疊,d的左端點就要?于a,b的右端點的最?值,與所有區間按照左端點排序不符。
    綜上所述,所有區間按照按照「左端點」排序之后,「互相重疊的區間」都是「相鄰」的
#include <bits/stdc++.h>
using namespace std;const int N = 1010;int n;
double d;
struct node
{double l, r;
}a[N];bool cmp(node& x, node& y)
{return x.l < y.l;    
}int main()
{int cnt = 0;while (cin >> n >> d, n && d){cnt++;bool flg = false;for (int i = 1; i <= n; i++){double x, y; cin >> x >> y;if (y > d) flg = true;double l = sqrt(d * d - y * y);a[i].l = x - l, a[i].r = x + l;}cout << "Case " << cnt << ": ";if (flg) cout << -1 << endl;else{sort(a+1, a+n+1, cmp);int ret = 1;double r = a[1].r;for (int i = 2; i <= n; i++){double left = a[i].l, right = a[i].r;if (left <= r){r = min(r, right);}else{ret++;r = right;}}cout << ret << endl;}}return 0;
}
P2887 [USACO07NOV] Sunscreen G - 洛谷

思考具體解法,從下?的情況中,篩選出沒有特別明顯的反例的組合:

  1. 區間按照左端點從?到?+防曬霜從?到?(優先選?);
  2. 區間按照左端點從?到?+防曬霜從?到?(優先選?);
  3. 區間按照左端點從?到?+防曬霜從?到?(優先選?);
  4. 區間按照左端點從?到?+防曬霜從?到?(優先選?);
  5. 區間按照右端點從?到?+防曬霜從?到?(優先選?);
  6. 區間按照右端點從?到?+防曬霜從?到?(優先選?)。
  7. 區間按照右端點從?到?+防曬霜從?到?(優先選?);
  8. 區間按照右端點從?到?+防曬霜從?到?(優先選?)。
    雖然看似很多,但是很容易在錯誤的策略中舉出「反例」。
  • 區間按照左端點從小到大,優先選較小的點:
    ![[Pasted image 20250405210201.png]]

第一個區間選了a之后,b這個點就沒辦法分配了
實際上應該把a給第二個區間,b給第一個區間

  • 區間按照左端點從小到大,優先選較大的點:
    ![[Pasted image 20250405210416.png]]

第一個區間選了b之后,a這個點就沒辦法分配了
實際上應該把b給第二個區間,a給第一個區間

  • 區間按左端點從大到小,優先選較小的點:
    ![[Pasted image 20250405210732.png]]

第一個區間選了a之后,b這個點就沒辦法分配了
實際上應該把a給第二個區間,b給第一個區間

  • 區間按左端點從大到小,優先選較大的點:
    ![[Pasted image 20250405211155.png]]

較小的點能夠更好地被后面的區間選擇

  • 區間按右端點從小到大,優先選較小的點:
    較大的點能夠更好地被后面的區間選擇
  • 區間按照右端點從小到大,優先選較大的點:
    ![[Pasted image 20250405211529.png]]

第一個區間選了b之后,a這個點就沒辦法分配了
實際上應該把b給第二個區間,a給第一個區間

  • 區間按右端點從大到小,優先選較小的點:
    ![[Pasted image 20250405212006.png]]

把a給了第一個區間以后,b就沒辦法分配了
實際上應該把b給第一個區間,a給第二個區間

  • 區間按右端點從大到小,優先選較大的點:
    ![[Pasted image 20250405212450.png]]

第一個區間選了b之后,a這個點就沒辦法分配了
實際上應該把b給第二個區間,a給第一個區間

綜上所述,有兩種組合沒有明顯的反例,分別是:

  1. 區間按照「左端點從?到?」排序,防曬霜從?到?排序,「優先選擇較?」的防曬霜;
  2. 區間按照「右端點從?到?」排序,防曬霜從?到?排序,「優先選擇較?」的防曬霜。
    實際上兩種情況都是正確的,我們取其?證明?下,另?種證明?式類似。

可以?「交換論證法」證明?式?的正確性:
從前往后依次?較「貪?解」和「最優解」針對每?個區間的決策,當找到第?個區間,它們的「分配決策不同」時:設貪?解?的是a防曬霜,最優解?的是b防曬霜,因為貪?解選的是最?的,所以有 a ≤ b a \le b ab
此時關于a 防曬霜的使?情況,可以分以下?種情況:

  1. a防曬霜在「最優解中沒有使?」,那么我們可以直接?a防曬霜替換b防曬霜,此時最優解的「最優性」并沒有損失,那么貪?解就和最優解決策?致;
  2. a防曬霜在「最優解的后續決策中使?了」,設b使?的區間是 [ x b , y b ] [x_{b},y_{b}] [xb?,yb?],a使?的區間是 [ x a , y a ] [x_{a},y_{a}] [xa?,ya?]
    易得:
    x b ≤ b ≤ y b , x a ≤ a ≤ y a x_{b} \le b \le y_{b}, x_{a} \le a \le y_{a} xb?byb?,xa?aya?
    因為我們是按照右端點從?到?排序的,所以 y a ≥ y b y_{a} \ge y_{b} ya?yb?
    綜上:
    x a ≤ a ≤ b ≤ y b ≤ y a x_{a} \le a \le b \le y_{b} \le y_{a} xa?abyb?ya?
    所以b也可以作?于「a作?的區間」,也就是在最優解中「a,b可以互換」,進?就轉換成貪?解。
    因此,針對每?個位置,我們都可以把最優解在「不失去其最優性的前提下」,轉化成「貪?解」
#include <bits/stdc++.h>
using namespace std;const int N = 2510;int n, m;
struct node
{int x;int y;
}a[N], b[N];bool cmp(node& x, node& y)
{return x.x > y.x;
}int main()
{cin >> n >> m;for (int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y;for (int i = 1; i <= m; i++) cin >> b[i].x >> b[i].y;sort(a+1, a+1+n, cmp); //按左端點從大到小排序sort(b+1, b+1+m, cmp); //按陽光強度從大到小排序int ret = 0;for (int i = 1; i <= n; i++){int l = a[i].x, r = a[i].y;for (int j = 1; j <= m; j++){int w = b[j].x, &cnt = b[j].y;if (cnt == 0) continue;if (w < l) break;if (w > r) continue;ret++;cnt--;break;}}cout << ret << endl;return 0;
}
P2859 [USACO06FEB] Stall Reservations S - 洛谷

按照「起始時間」對所有奶?「從?到?」排序,然后「從前往后」依次安排每?頭奶?,設這頭奶?的產奶的時間區間是[a, b]

  • 在已經有?的所有?棚?,如果「結束時間?于a」,就可以把這頭奶?放在這個?棚??;如果有很多符合要求的,可以隨便找?個。因為我們是按照起始時間從?到?排序,只要這些?棚都符合要求,對于后?的奶???也都符合要求。不妨找結束時間最早的,?便判斷。
  • 如果所有已經有?的?棚的「結束時間都?于a 」,那么這頭?只能??單獨開?個?棚。
    這個貪?策略是?較符合我們「常識」的,盡量優的安排每?頭?
#include <bits/stdc++.h>
using namespace std;const int N = 5e4 + 10;int n;
struct node
{int x; //起始時間 / 結束時間int y; //終止時間 / 牛棚編號int z; //排序之前的編號bool operator<(const node& a) const{return x > a.x;}}a[N];int ret[N]; //存最終結果bool cmp(node& x, node& y)
{return x.x < y.x;
}int main()
{cin >> n;for (int i = 1; i <= n; i++){cin >> a[i].x >> a[i].y;a[i].z = i;}sort(a+1, a+1+n, cmp);int num = 1;priority_queue<node> heap;ret[a[1].z] = 1;heap.push({a[1].y, 1});for (int i = 2; i <= n; i++){int l = a[i].x, r = a[i].y;if (l <= heap.top().x) //無法放在已經分配的牛棚里{num++;ret[a[i].z] = num;heap.push({r, num});}else{node t = heap.top(); heap.pop();ret[a[i].z] = t.y;heap.push({r, t.y});}}cout << num << endl;for (int i = 1; i <= n; i++) cout << ret[i] << endl;return 0;
}

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

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

相關文章

用C語言控制鍵盤上的方向鍵

各位同學&#xff0c;大家好&#xff01;相信大家在學習C語言的過程中&#xff0c;都和我一樣&#xff0c;經常使用scanf函數來接受字符&#xff0c;數字&#xff0c;這些標準輸入信息&#xff0c;來實現自己設計的程序效果。 而我突然有一天&#xff08;對就是今天&#xff09…

特殊的質數肋骨--dfs+isp

1.dfs全排列組數&#xff0c;an記得還原 2.如果范圍確定且只比較質數&#xff0c;isp比線性篩快&#xff0c;主要這個范圍太大了 https://www.luogu.com.cn/problem/P1218 #include<bits/stdc.h> using namespace std; #define N 100011 typedef long long ll; typed…

定積分的應用(4.39-4.48)

battle cry 前言4.394.404.414.424.434.444.454.464.474.48 前言 題目確實比較多。slow down and take your time. 4.39 狂算了一遍&#xff0c;然后發現不是計算出問題了&#xff0c;是積分上下限寫錯了。還有把函數代進去也出了一點問題。 點火公式一家人我不記得&#x…

如何高效使用 Ubuntu 中文官方網站

Ubuntu 中文官方網站 一、快速導航與核心模塊 首頁焦點區 頂部菜單欄:快速訪問「下載」「文檔」「支持」「商店」等核心功能。輪播圖區:展示最新版本(如 Ubuntu 24.04 LTS)和特色功能(如 Ubuntu Pro 訂閱服務)。搜索框:支持中文關鍵詞搜索(如 "邊緣計算"),…

form實現pdf文件轉換成jpg文件

說明&#xff1a; 我希望將pdf文件轉換成jpg文件 請去下載并安裝 Ghostscript&#xff0c;gs10050w64.exe 配置環境變量&#xff1a;D:\Program Files\gs\gs10.05.0\bin 本地pdf路徑&#xff1a;C:\Users\wangrusheng\Documents\name.pdf 輸出文件目錄&#xff1a;C:\Users\wan…

Spring 核心技術解析【純干貨版】- XVIII:Spring 網絡模塊 Spring-WebSocket 模塊精講

在現代 Web 開發中&#xff0c;實時通信已成為提升用戶體驗的關鍵技術之一。傳統的 HTTP 輪詢方式存在較高的延遲和帶寬開銷&#xff0c;而 WebSocket 作為一種全雙工通信協議&#xff0c;能夠在客戶端和服務器之間建立持久連接&#xff0c;實現高效的雙向數據傳輸。 Spring 框…

VirtualBox安裝FnOS

1.下載FnOS鏡像 下載網址&#xff1a; https://www.fnnas.com/2.創建虛擬機 虛擬機配置如圖所示&#xff08;注意操作系統類型和網卡配置&#xff09; &#xff08;注意啟動順序&#xff09; 3.啟動虛擬機 網卡類型選擇橋接的Virtual Adapter 如果沒有IP地址或者IP地址無法…

java根據集合中對象的屬性值大小生成排名

1&#xff1a;根據對象屬性降序排列 public static <T extends Comparable<? super T>> LinkedHashMap<T, Integer> calculateRanking(List<ProductPerformanceInfoVO> dataList, Function<ProductPerformanceInfoVO, T> keyExtractor) {Linked…

grep命令: 過濾

[rootxxx ~]# grep root /etc/passwd [rootxxx ~]# grep -A 2 root /etc/passwd -A #匹配行后兩行 [rootxxx ~]# grep -B 2 root /etc/passwd -B #匹配行前兩行 [rootxxx ~]# grep -C 2 root /etc/passwd -C #前后2行 [rootxxx ~]# grep -n root /…

二十種中藥果實識別分類系統,Python/resnet18/pytorch

二十種中藥果實識別分類系統,Python/resnet18/pytorch 基于pytorch訓練, resnet18網絡&#xff0c;可用于訓練其他分類問題&#xff0c;也可自己重新訓練 20類中藥材具體包括&#xff1a;(1) 補骨脂&#xff0c;(2) 草豆蔻&#xff0c;(3) 川楝子&#xff0c;(4) 地膚子&…

SpringBoot啟動run方法分析

SpringBoot啟動run方法分析 1.場景引入 在項目啟動的時候&#xff0c;有時候我們需要在啟動的時候&#xff0c;執行一些邏輯。 比如說&#xff0c;項目啟動的時候&#xff0c;我想把一些熱門商品的數據加載到緩存中去&#xff1b; 比如說&#xff0c;自定義了一個netty服務…

Linux信號——信號的處理(3)

信號是什么時候被處理&#xff1f; 進程從內核態&#xff0c;切換到用戶態的時候&#xff0c;信號會被檢測處理。 內核態&#xff1a;操作系統的狀態&#xff0c;權限級別高 用戶態&#xff1a;你自己的狀態 內核態和用戶態 進程地址空間第三次 所謂的系統調用本質其實是一堆…

MySQL篇(四)事務相關知識詳解

MySQL篇(四&#xff09;事務相關知識詳解 MySQL篇(四&#xff09;事務相關知識詳解一、事務的特性&#xff08;ACID&#xff09;原子性&#xff08;Atomicity&#xff09;一致性&#xff08;Consistency&#xff09;隔離性&#xff08;Isolation&#xff09;持久性&#xff08;…

SpringBoot定時任務深度優化指南

精心整理了最新的面試資料和簡歷模板&#xff0c;有需要的可以自行獲取 點擊前往百度網盤獲取 點擊前往夸克網盤獲取 SpringBoot定時任務深度優化指南 引言 在分布式系統架構中&#xff0c;定時任務是實現業務邏輯自動化的重要組件。SpringBoot通過Scheduled注解提供了便捷的…

MySQL表結構導出(Excel)

目錄 一、java實現MySQL表結構導出&#xff08;Excel&#xff09; 二、python實現MySQL表結構導出&#xff08;Excel&#xff09; 又到了寫畢設的時候了&#xff0c;計算機專業在寫論文第四章系統設計的時候肯定會遇到和我一樣的難題——要在論文中將數據庫的表結構以表格形式…

Android使用OpenGL和MediaCodec渲染視頻

目錄 一&#xff0c;借助MediaCodec封裝解碼工具類VideoCodec 二&#xff0c;使用OpenGl繪制視頻封裝SoulFilter 一&#xff0c;借助MediaCodec封裝解碼工具類VideoCodec /*** 解碼工具類* 解碼完成后的數據 通過 ISurface 回調出去*/ public class VideoCodec {private ISu…

day39——輸入操作:多值輸入

數組輸入&#xff1a; int main() {//***** 1、多值輸入&#xff08;C&#xff09;/*輸入&#xff1a;3 --> 3個值5 4 9*/int n;cin >> n; //輸入個數const int MAX_SIZE 0xFFFF;//限定最大個數int a[MAX_SIZE];for (int i 0; i < n; i) {//用 n 作控制輸入…

第九課:LoRA模型的原理及應用

文章目錄 Part.01 3種LoRA的使用方式Part.02 5種LoRA的應用方向Part.01 3種LoRA的使用方式 LoRA能夠在家用級設備上訓練,實現對Checkpoint在某些方面的微調使用Lora的三種方式:放置Lora模型到目錄中,然后作為提示詞的一部分輸入。點擊生成按鈕下面的“畫”,然后打開Additio…

Cortex-M3 NVIC可以控制異常向量表的哪些部分

Cortex-M3 的 NVIC(嵌套向量中斷控制器)不直接控制整個異常向量表,但可以管理向量表中與中斷相關的部分行為。以下是 NVIC 對異常向量表的具體控制范圍和相關機制: 1. NVIC 直接控制的部分 NVIC 主要管理 外部中斷(IRQ) 和部分 系統異常 的行為,但對向量表本身的存儲位…

雙向鏈表增刪改查的模擬實現

本章目標 0.雙向鏈表的基本結構 1.雙向鏈表的初始化 2.頭插尾插 3.頭刪尾刪 4.查找與打印 5.在指定位置之前插入數據/在指定位置之后插入數據 6.在指定位置之前刪除數據/在指定位置之后刪除數據 7.銷毀鏈表 0.雙向鏈表的基本結構 本章所實現的雙向鏈表是雙向循環帶頭鏈表,是…