區間貪心

目錄

1.貪心算法的思想

2.區間貪心算法常用的一些題目類型

1.選擇最多不相交區間問題

P2970 [USACO09DEC] Selfish Grazing S

?1.思路分析

2.上代碼

2.區間選點問題

P1250 種樹

1.題目

2.方法一

1.代碼解釋

?3.方法二

3.區間合并問題

P2434 [SDOI2005] 區間

1. 思路分析

2.上代碼

4.區間覆蓋問題

?P1668 [USACO04DEC] Cleaning Shifts S

1.思路分析

?2.代碼解釋

5.區間分組

T471772 cici排課

?編輯?1.一點點思路

2.代碼實現與算法思路

3.舉一反三

3.遇到了(區間)貪心的題我們應該怎么做

end👍🏻?ok?


1.貪心算法的思想

貪心算法是從問題的初始狀態出發,通過若干次的貪心選擇而得到的最優值(或較優值)的1種求解問題策略,即貪心策略。

2.區間貪心算法常用的一些題目類型

1.選擇最多不相交區間問題

P2970 [USACO09DEC] Selfish Grazing S

洛谷:P2970 [USACO09DEC] Selfish Grazing S - 洛谷 | 計算機科學教育新生態 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P2970

?1.思路分析

題題目的大概意思就是給定我們N個區間,求最多不相交區間有多少個。

我們可以按照區間的右端點從小到大排序

?然后我們創建一個變量命名為j和一個變量cnt(計數),再次循環整個結構體(輸入的那些區間,已經排序完), 如果循環到的這個區間的左端點在標簽變量j的右邊,把j更新為這個區間的左端點,cnt++

2.上代碼
#include <bits/stdc++.h>
using namespace std;
struct M{int s,e;
}a[500005];
bool cmp(M x,M y){return x.e <y.e;
}
int main(){int n;cin >> n;for(int i =0; i < n; i++){cin >> a[i].s >> a[i].e;}sort(a,a+n,cmp);int j = -1,cnt = 0;for (int i =0; i < n; i++){if (a[i].s >= j){j = a[i].e;cnt ++;}}cout << cnt;return 0;
}

2.區間選點問題

P1250 種樹

洛谷:

P1250 種樹 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1250

1.題目

?

2.方法一

?把所有樹都往右邊種,為了讓他們重疊區間的更多,而且重疊的部分大部分都在右側,我們就要讓這些區間按右端點,從小到大排序,下圖是我列舉的樣例。

首先先把樣例歸一整一下(排序)

123456789
||
|
|

從第一個開始在尾巴上種樹,如果這個區間內已經種到了t[i]棵的話就不種了 , 如果沒有種到這么多棵樹那就得從后往前,循環種樹只要種到為止.(括號代表已經種上樹了,+1代表多種一棵樹)

123456789
|(|)+1(】)+1
(【)(|)(】)被底下的人種上了
(【)(|)+1
(【)+1(】)+1

其實這樣的話更形象,就是有點亂:

123456789
([)|(|[)(]|[)(]|)]([)(])

?同樣顏色是一個區間

貪心加模擬的思想

1.代碼解釋
#include <bits/stdc++.h>
using namespace std;
bool v[100005];
struct Sa{int a,b,c;
}s[100005];
bool cmp(Sa x,Sa y){return x.b < y.b;
}

我定義了一個叫做s的 結構體,s[i].a = b,s[i].b = e,s[i].c = t(這些值和題目中的數);

這一段代碼靠下的cmp是排序函數

v數組就是大街,就是那個有點亂的圖

___________________________優雅的分界線_______________________

輸入+排序?

int main(){int q;int n;cin >> q>> n;for (int i =1; i <= n; i++){cin >> s[i].a >> s[i].b >> s[i].c;}sort(s+1,s+n+1,cmp);

___________________________優雅的分界線_______________________

    int cnt = 0;for (int i = 1; i <= n; i++){int sum = 0;for (int j = s[i].a; j <= s[i].b; j++){if (v[j]) sum ++;}if (sum >= s[i].c){continue;}

?循環的第一部分, sum的值是在這個區間內種了多少棵樹,如果已經種夠了那就不用循環這一次看下一次區間.

___________________________優雅的分界線_______________________

		sum = s[i].c - sum;cnt += sum;for (int j = s[i].b; j >= s[i].a; j--){if (v[j] == 0){sum --;v[j] = 1;}if (sum == 0){break;}}

?循環的第二部分,sum值變成還差多少棵樹,總共棵數增加sum,循環種樹(倒過來循環);

___________________________優雅的分界線_______________________

最后輸出cnt;

___________________________優雅的分界線_______________________

總體代碼

#include <bits/stdc++.h>
using namespace std;
bool v[100005];
struct Sa{int a,b,c;
}s[100005];
bool cmp(Sa x,Sa y){return x.b < y.b;
}
int main(){int q;int n;cin >> q>> n;for (int i =1; i <= n; i++){cin >> s[i].a >> s[i].b >> s[i].c;}sort(s+1,s+n+1,cmp);int cnt = 0;for (int i = 1; i <= n; i++){int sum = 0;for (int j = s[i].a; j <= s[i].b; j++){if (v[j]) sum ++;}if (sum >= s[i].c){continue;}sum = s[i].c - sum;cnt += sum;for (int j = s[i].b; j >= s[i].a; j--){if (v[j] == 0){sum --;v[j] = 1;}if (sum == 0){break;}}}cout << cnt;return 0;
}
?3.方法二

換1種方法可以反過來運算,就像加有減,除有乘

也就是從左到右去種樹,排序的時候按照左端點從小到大排序,

直接演示代碼吧!

#include <bits/stdc++.h>
using namespace std;
bool v[100005];
struct Sa{int a,b,c;
}s[100005];
bool cmp(Sa x,Sa y){return x.a > y.a;
}
int main(){int q;int n;cin >> q>> n;for (int i =1; i <= n; i++){cin >> s[i].a >> s[i].b >> s[i].c;}sort(s+1,s+n+1,cmp);int cnt = 0;for (int i = 1; i <= n; i++){int sum = 0;for (int j = s[i].a; j <= s[i].b; j++){if (v[j]) sum ++;}if (sum >= s[i].c){continue;}sum = s[i].c - sum;cnt += sum;for (int j = s[i].a; j <= s[i].b; j++){if (v[j] == 0){sum --;v[j] = 1;}if (sum == 0){break;}}}cout << cnt;return 0;
}

3.區間合并問題

P2434 [SDOI2005] 區間

網址:

P2434 [SDOI2005] 區間 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P2434

?

1. 思路分析

給出若干個區間讓我們輸出它們可以合并出來最少的區間(個數,但是輸出區間)。

1.按照左端點排序

2.排序完了以后定義兩個變量L和R,L=第一個區間的左端點,R=第一個區間的右端點

3.遍歷一遍這些區間(不包含第一個)

4.如果這個區間的左端點(開端),大于了R(這個區間不在我們L~R里不包含它),輸出L和R,把L的值更新為這個區間的左端點(更新一下整個區間)

5. R的值和區間的右端點做比較選取最大的那個值更新R

2.上代碼
#include <bits/stdc++.h>
using namespace std;
struct B{int l,r;
}a[1000005];
bool cmp(B x, B y){return x.l < y.l;
}
int main(){int n;cin >> n;for (int i = 0; i < n; i++){cin >> a[i].l >> a[i].r;}sort(a,a+n,cmp);int R = a[0].r,L = a[0].l;for (int i=1; i <n ; i++){if (a[i].l > R){cout << L << " " << R << "\n";L = a[i].l;}R = max(a[i].r,R);}cout << L << " " << R << "\n";return 0;
}

4.區間覆蓋問題

?P1668 [USACO04DEC] Cleaning Shifts S

?P1668 [USACO04DEC] Cleaning Shifts S - 洛谷 | 計算機科學教育新生態 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1668

這道題題目的意思是:給定我們一個區間1~T,我們有N個小區間,請問需要最少幾個小區間可以覆蓋整個大區間(1~T),請注意兩個區間之間可以差一,只要每個時間段都有奶牛也可以,比如(1,2)(3,4)它們就可以并到一起去。雖然它講起來是時間段但是它做起來是時間點。

1.思路分析

圖片分析請看下圖

?2.代碼解釋
#include <bits/stdc++.h>
using namespace std;
struct Sa{int a,b;
}s[100005];
bool cmp(Sa x,Sa y){return x.a < y.a;
}
int main(){int n,t;cin >> n >> t;int cnt=0;for (int i= 1; i <= n; i++){cin >> s[i].a >> s[i].b;}sort(s+1,s+n+1,cmp);

結構體函數+排序函數cmp按照左端點從小到大排+輸入與排序

int l = 1,r = -1;for (int i = 1; i <= n;){if (s[i].a > l){cout <<-1;return 0;}

如果左端點最靠前的那個區間,左端點還是大于L,說明整個區間結構體沒有一個左端點小于等于L,輸出負一不能實現

while (i <= n and s[i].a <= l){r = max(s[i].b,r);i++;}cnt ++;

去看,左端點小于等于,而且右端點是最大的.增加區間段數(cnt).

if (r >= t){cout << cnt;return 0;}l = r +1;}

如果我們的最大值已經超過了T輸出cnt,把L更新為r+1.

cout << -1;return 0;
}

對如果在循環里都沒結束的話,說明不可以實現輸出-1

?總體代碼

#include <bits/stdc++.h>
using namespace std;
struct Sa{int a,b;
}s[100005];
bool cmp(Sa x,Sa y){return x.a < y.a;
}
int main(){int n,t;cin >> n >> t;int cnt=0;for (int i= 1; i <= n; i++){cin >> s[i].a >> s[i].b;}sort(s+1,s+n+1,cmp);int l = 1,r = -1;for (int i = 1; i <= n;){if (s[i].a > l){cout <<-1;return 0;}while (i <= n and s[i].a <= l){r = max(s[i].b,r);i++;}cnt ++;if (r >= t){cout << cnt;return 0;}l = r +1;}cout << -1;return 0;
}

5.區間分組

呃……,這道題你們就看圖片吧!

T471772 cici排課

?1.一點點思路

這個題目不在于老師的編號是多少哪個老師該上哪節課,只用求出老師的個數就行。

只要有課程下課了的話我們就可以釋放老師,如果釋放了新課,既要把新課排給被釋放的老師.

2.代碼實現與算法思路

#思路

我們輸給兩個數組(a,b),注意在這里不要用區間的眼光看這兩個數組, 數組要分開來排序, a從小到大排序b也從小到大排序,定義一個變量cnt(老師數量)然后循環:

a的i號位的數與b的第j號位對比,如果小于等于B的第j號位{

????????cnt++

????????查看a的i+1號位//也就是i++;

}//這個循環也就是循環到a[i]>b[j],看一看在b[j]這個課結束之前,還會上多少節課

如果b[j]比a[i]為小的話{//也就是說有老師被釋放出來了

? ? ? ? cnt --

? ? ? ? j++;//看下一位

}

#代碼實現,增加一些判斷我會進行注釋?

為什么要求最大值,因為這種方法是最值的,而求最大值是要求這種最值方法需要多少名老師

#include <bits/stdc++.h>
using namespace std;
int a[100005],b[100005];
int main(){int n;cin >> n;for (int i =0; i < n; i++){cin >> a[i] >> b[i];}sort(a,a+n);sort(b,b+n);int i = 0,j = 0,big = -1,cnt = 0;while (1){while (i < n and a[i] <= b[j]){cnt ++;big = max(cnt,big);//求最大值i ++;}if (i >= n) break;  //如果要上的課都檢查完了就退出輸出最大值while (j < n and b[j] < a[i]){cnt --;j ++;}}cout << big;return 0;
}
3.舉一反三

這道題會讓我們想起“匹配括號”,雖然不知道這個題名字叫做什么,但是題目的大致意思如下:

輸入一個字符串字符串用“(”和“)”組成,“(”和“)”可以形成一組,請問輸入的字符串有沒有多余的括號。如果沒有輸出“yes”如果有輸出“no”(不加引號)。

就比如輸入:

((())())

很明顯是匹配上了的

請看下列表格是我們這道題的算法,左括號加一,右括號減一

12321210

如果最后等于零的話就可以匹配成功.

不過你可能會問這道題和cici排課有什么關系 ,你可以把題目改編一下變成:

還是輸入一個字符串,每一個符號(左括號、右括號)之間,輸出我們的cnt最大值。

我們借鑒上面的表格,這個題目就可以輸出3

而我們的CiCi排課也是同樣的道理,左括號是開始上課,右括號是結束上課,問你老師人數的最大值.

3.遇到了(區間)貪心的題我們應該怎么做

找出我們要排序的順序按什么排序,

再進行循環,加入題目的要求

最后說一句特殊題目特殊判斷,一定要變得靈活起來.

end👍🏻?

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

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

相關文章

中科海訊 C++初級研發工程師筆試題目

C語言中的const關鍵字有什么作用&#xff1f;為什么要使用const關鍵字&#xff1f; 1 const修飾的變量將會被放到常量區&#xff0c;避免被意外的改動。 const修飾的常量比#define修飾的有更多的優勢&#xff0c;比如可以調試&#xff0c;類型檢查等 2 const修飾的參數可做輸入…

Java集合面試題

Java集合框架 1、List、Set、Map的區別2、ArrayList、LinkedList、Vector區別3、為什么數組索引從0開始&#xff0c;而不是從1開始&#xff1f;4、ArrayList底層的實現原理5、紅黑樹、散列表6、HashMap的底層原理7、HashMap的put方法具體流程8、HashMap的擴容機制9、HashMap是怎…

南方科技大學馬永勝教授給年輕人使用AI工具上的建議

摘要 - 1. AI的未來&#xff0c;是機器人和機器人之間的合作&#xff1b; 2. 行業的發展方向是需求決定的&#xff0c;不要做同質化的發展&#xff0c;要做專/精/特/新&#xff1b; 3. 新質生產力 &#xff08; 科學技術革命性突破 生產要素創新型配置 產業深度轉型升級&…

java通過poi-tl導出word實戰詳細步驟

文章目錄 與其他模版引擎對比1.引入maven依賴包2.新建Word文檔exportWprd.docx模版3.編寫導出word接口代碼4.導出成果 poi-tl是一個基于Apache POI的Word模板引擎&#xff0c;也是一個免費開源的Java類庫&#xff0c;你可以非常方便的加入到你的項目中&#xff0c;并且擁有著讓…

貪心算法-以高校教材管理系統為例

1.貪心算法介紹 1.算法思路 貪心算法的基本思路是從問題的某一個初始解出發一步一步地進行&#xff0c;根據某個優化測度&#xff0c;每一 步都要確保能獲得局部最優解。每一步只考慮一 個數據&#xff0c;其選取應該滿足局部優化的條件。若下 一個數據和部分最優解連在一起…

Pix4Dmapper:無人機測繪的革命性工具

在現代測繪和地理信息系統&#xff08;GIS&#xff09;領域&#xff0c;Pix4Dmapper無疑是一款革命性的工具。作為一名長期使用這款軟件的用戶&#xff0c;我深深感受到它在工作中的重要性和便利性。Pix4Dmapper不僅僅是一款軟件&#xff0c;更是測繪工作者的得力助手&#xff…

285個地級市出口產品質量及技術復雜度(2011-2021年)

出口產品質量與技術復雜度&#xff1a;衡量國家競爭力的關鍵指標 出口產品質量是衡量國內企業生產的產品在國際市場上競爭力的重要標準。它不僅要求產品符合國際標準和目標市場的法律法規&#xff0c;而且需要保證產品質量的穩定性和可靠性。而出口技術復雜度則進一步體現了一…

新一代信息技術及應用

關于云計算的描述不正確的是&#xff08; &#xff09;。 A 云計算可以通過網絡連接&#xff0c;用戶通過網絡接入“云”中并獲得有關的服務&#xff0c;“云”內節點之間也通過內部的網絡相連 B 云計算可以快速、按需、彈性服務&#xff0c;用戶可以按照實際需求迅速獲取或釋放…

[Python學習篇] Python面向對象——類

面向對象是什么&#xff1f; 面向對象&#xff08;Object-Oriented Programming&#xff0c;簡稱OOP&#xff09;是一種編程范式&#xff0c;它使用“對象”來設計應用程序和計算機程序。OOP的核心概念包括類&#xff08;Class&#xff09;、對象&#xff08;Object&#xff09…

批量下載手機中APP程序中文件

需求 利用 adb pull 下載手機中app的某目錄 adb pull 命令本身不支持直接下載整個目錄&#xff08;文件夾&#xff09;及其所有子目錄和文件作為一個單一的操作。但是&#xff0c;可以通過一些方法來間接實現這一目的。 方法 1. 首先將要下載的目錄進行 tar 打包 # 在 And…

Python面試題:Python 中的 `property` 函數有什么用?

在 Python 中&#xff0c;property 函數用于創建和管理類中的屬性。它允許你將方法轉換為屬性&#xff0c;這樣你可以像訪問變量一樣訪問這些方法。這對于控制屬性的訪問和修改非常有用&#xff0c;因為它允許你在屬性訪問時執行額外的邏輯&#xff08;如驗證或計算&#xff09…

光通信領域常見的會議和期刊總結

在高速光通信小組待了一年&#xff0c;對我們領域主要的會議和期刊也有了一定的了解&#xff0c;所以總結一下我們可以投的期刊或會議有哪些。會議一般有OFC、ECOC、CLEO、OECC、ACP等&#xff0c;期刊則有OE、OL、PTL、JLT、PJ、AO、JOSA等&#xff0c;下面簡單介紹一下。 先…

【atcoder】習題——位元枚舉

題意&#xff1a;求i&M的popcount的和&#xff0c;i屬于0……N 主要思路還是變加為乘。 舉個例子N22&#xff0c;即10110 假設M的第3位是1&#xff0c;分析N中&#xff1a; 00110 00111 00100 00101 發現其實等價于 0010 0011 0000 0001 也就是左邊第4位和第5…

算法學習筆記(8.1)-動態規劃入門

目錄 問題特性&#xff1a; 最優子結構&#xff1a; 代碼示例&#xff1a;&#xff08;動態規劃最優子結構&#xff09; 上述最小代價爬樓梯的運行過程&#xff1a; 代碼示例&#xff1a; 無后效性&#xff1a; 解析&#xff1a; 具體過程圖示如下&#xff1a; 具體的…

如何為IP申請SSL證書

目錄 以下是如何輕松為IP地址申請SSL證書的詳細步驟&#xff1a; 申請IP證書的基本條件&#xff1a; 申請IP SSL證書的方式&#xff1a; 確保網絡通信安全的核心要素之一&#xff0c;是有效利用SSL證書來加密數據傳輸&#xff0c;特別是對于那些直接通過IP地址訪問的資源。I…

使用 Azure DevOps Pipelines 生成 .NET Core WebJob 控制臺應用 CI/CD

Web 應用程序通常需要作為后臺任務運行的進程&#xff0c;并在特定時間間隔進行計劃或在事件中觸發。它們不需要花哨的 IO 接口&#xff0c;因為重點是過程而不是輸出。Azure WebJobs 提供了出色的支持&#xff0c;通常在云環境中通過 Web 控制臺應用程序來實現此目的。WebJob …

企業數字化轉型中的低代碼開發平臺應用:釋放創新潛能

隨著信息技術的飛速發展&#xff0c;企業數字化轉型已成為行業趨勢。在這場轉型浪潮中&#xff0c;低代碼開發平臺以其獨特的優勢&#xff0c;成為眾多企業實現快速迭代、高效創新的得力助手。本文將深入探討低代碼開發平臺在企業數字化轉型中的應用&#xff0c;以及如何幫助企…

Mac平臺虛擬機 Parallels Desktop v19.4.1,支持M1/M2/M3芯片組

Parallels Desktop for Mac是功能強大靈活度高的虛擬化方案&#xff0c;無需重啟即可在同一臺電腦上隨時訪問Windows和Mac兩個系統上的眾多應用程序。從僅限于PC的游戲到生產力軟件&#xff0c;Parallels Desktop都能幫您實現便捷使用。Parallels Desktop 是一款專業的Mac虛擬機…

Docker搭建kafka+zookeeper以及Springboot集成kafka快速入門

參考文章 【Docker安裝部署KafkaZookeeper詳細教程】_linux arm docker安裝kafka-CSDN博客 Docker搭建kafkazookeeper 打開我們的docker的鏡像源配置 vim /etc/docker/daemon.json 配置 { "registry-mirrors": ["https://widlhm9p.mirror.aliyuncs.com"…

vue父子組件通信實現模糊搜索功能

我遇到的問題&#xff1a; 我的搜索框在父頁面&#xff0c;靜態數據都在子頁面。怎么實現模糊查詢數據&#xff1f; 昨天的嘗試&#xff1a;先把搜索的內容數據存到session里&#xff0c;然后從session里拿&#xff0c; 結果&#xff1a;存是存進去了&#xff0c;卻拿不到。應…