【反悔堆 優先隊列 臨項交換 決策包容性】630. 課程表 III

本文涉及知識點

貪心 反悔堆 優先隊列 臨項交換

Leetcode630. 課程表 III

這里有 n 門不同的在線課程,按從 1 到 n 編號。給你一個數組 courses ,其中 courses[i] = [durationi, lastDayi] 表示第 i 門課將會 持續 上 durationi 天課,并且必須在不晚于 lastDayi 的時候完成。
你的學期從第 1 天開始。且不能同時修讀兩門及兩門以上的課程。
返回你最多可以修讀的課程數目。
示例 1:
輸入:courses = [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]]
輸出:3
解釋:
這里一共有 4 門課程,但是你最多可以修 3 門:
首先,修第 1 門課,耗費 100 天,在第 100 天完成,在第 101 天開始下門課。
第二,修第 3 門課,耗費 1000 天,在第 1100 天完成,在第 1101 天開始下門課程。
第三,修第 2 門課,耗時 200 天,在第 1300 天完成。
第 4 門課現在不能修,因為將會在第 3300 天完成它,這已經超出了關閉日期。
示例 2:
輸入:courses = [[1,2]]
輸出:1
示例 3:
輸入:courses = [[3,2],[4,3]]
輸出:0
提示:
1 <= courses.length <= 104
1 <= durationi, lastDayi <= 104

臨項交換+反證法+決策包容性

證明過程比較復雜,結論如下:
性質一:只需要按結束時間升序枚舉。
性質二:按性質一排序后,前i門課的最佳解:a,學的課程多更優。 b,相同課程結束時間早的更優。

利用臨項交換證明性質一

令最優解,按順序為:{{t1,d1},{t2,d2} ? \cdots ? {tk,dk}}
? \forall ?i ,如果di < d{i+1} ,則調整兩者的順序。不失一般性,假定i為1。
令調整前: 第x天開始執行{t1,d1},則說明:
x + t1 -1 <= d1 式子一
x + t1 + t2 -1 <= d2 式子二
式子二,結合t1 >=1 → \rightarrow x + t2 -1 <= d2
式子二結合假定d2 < d1 → \rightarrow x +t1 + t2 -1 <= d1
即調整后也合法。
所有相鄰的兩項調整后,di升序。故:我們枚舉的時候只需要考慮di升序。

反證法和決策包容性證明性質二

最佳結果:
學的課程多優于學的課程少。
學的課程相等,所用時間短的更優,早結束。
那么推導第i+1門課程的過程如下:
如果學完前i門后,能學第i+1門課程,則將第i+1門課加到最佳課程中。
否則,最佳課程中有課程的用時多于第i+1門課且用時最多的課,替換成第i+1門課。

反證法

假定前i門課的最優解是k門課,某個方案只有k-1門課。有如下推論:
一,某方案一定不劣與最優解的k-1門最短的課,否則用最優解的最短k-1門替換某方案。
二,某方案一定不優與最優解的k-1門最短的課,優于最短的k-1門,則優于任意k-1門。我們將最優解的前k-1替換成某方案會更優,與最優解矛盾。如果有重復課程都刪除,則刪除后,分別有k1和k1-1門課,仍然符合結論。
故:某方案就是最優解最短的k-1門課。

決策包容性

某方案如果不選擇第i+1門課,則一定劣與最優解。
如果最優接的后續狀態,能夠選擇k+1門,則最優解一定優于某方案。
余下情況,最優解的后續狀態有如下兩種可能:
{ 一,最優解的 k 門。 k 門的用時都小于等于第 i + 1 門。 二最優解的 ( k ? 1 ) 門 + 第 ( i + 1 ) 門。 o t h e r \begin{cases} 一,最優解的k門。&& k門的用時都小于等于第i+1門。 \\ 二 最優解的(k-1)門+ 第(i+1)門。 && other \\ \end{cases} {一,最優解的k門。二最優解的(k?1)+(i+1)門。??k門的用時都小于等于第i+1門。other?
某方案只有情況二,即:最優解方案包容某方案。

代碼

思路

小根堆headEndNeed記錄 {ti,d1}
我們處理完前i項課程的最終結果放到:headRes中。use記錄最佳結果的總用時。
學習完k+1門課,用是use + need,則學完最后一天的時間為use+need,從1開始。
時間復雜度: O(nlogn) 每門課的操作時間是log(n)。

核心代碼

class Solution {
public:int scheduleCourse(vector<vector<int>>& courses) {priority_queue<std::pair<int, int>, vector< std::pair<int, int>>, greater<>> headEndNeed;for (const auto& v : courses) {headEndNeed.emplace(make_pair(v[1], v[0]));}priority_queue<int> headRes;int use = 0;while (headEndNeed.size()) {auto [end, need] = headEndNeed.top();headEndNeed.pop();if (use + need  <= end) {headRes.emplace(need);use += need;}else {if (headRes.size() && (headRes.top() > need)) {use += (need - headRes.top());headRes.pop();headRes.emplace(need);}}}return headRes.size();}
};

單元測試

template<class T1, class T2>
void AssertEx(const T1& t1, const T2& t2)
{Assert::AreEqual(t1, t2);
}template<class T>
void AssertEx(const vector<T>& v1, const vector<T>& v2)
{Assert::AreEqual(v1.size(), v2.size());for (int i = 0; i < v1.size(); i++){Assert::AreEqual(v1[i], v2[i]);}
}template<class T>
void AssertV2(vector<vector<T>> vv1, vector<vector<T>> vv2)
{sort(vv1.begin(), vv1.end());sort(vv2.begin(), vv2.end());Assert::AreEqual(vv1.size(), vv2.size());for (int i = 0; i < vv1.size(); i++){AssertEx(vv1[i], vv2[i]);}
}namespace UnitTest
{	vector<vector<int>> courses;TEST_CLASS(UnitTest){public:TEST_METHOD(TestMethod00){courses = { {100, 200}, {200, 1300}, {1000, 1250}, {2000, 3200} };auto res = Solution().scheduleCourse(courses);AssertEx(3, res);}TEST_METHOD(TestMethod01){courses = { {1,2} };auto res = Solution().scheduleCourse(courses);AssertEx(1, res);}TEST_METHOD(TestMethod02){courses = { {3,2},{4,3} };auto res = Solution().scheduleCourse(courses);AssertEx(0, res);}};
}

擴展閱讀

視頻課程

先學簡單的課程,請移步CSDN學院,聽白銀講師(也就是鄙人)的講解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成戰斗了,為老板分憂,請學習C#入職培訓、C++入職培訓等課程
https://edu.csdn.net/lecturer/6176

相關推薦

我想對大家說的話
《喜缺全書算法冊》以原理、正確性證明、總結為主。
按類別查閱鄙人的算法文章,請點擊《算法與數據匯總》。
有效學習:明確的目標 及時的反饋 拉伸區(難度合適) 專注
聞缺陷則喜(喜缺)是一個美好的愿望,早發現問題,早修改問題,給老板節約錢。
子墨子言之:事無終始,無務多業。也就是我們常說的專業的人做專業的事。
如果程序是一條龍,那算法就是他的是睛

測試環境

操作系統:win7 開發環境: VS2019 C++17
或者 操作系統:win10 開發環境: VS2022 C++17
如無特殊說明,本算法用**C++**實現。

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

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

相關文章

WordPress網站違法關鍵詞字過濾插件下載text-filter

插件下載地址&#xff1a;https://www.wpadmin.cn/2025.html 插件介紹 WordPress網站違法關鍵詞字過濾插件text-filter由本站原創開發,支持中英文關鍵字自動替換成**號&#xff0c;可以通過自定義保存修改按鈕增加“預設關鍵字”&#xff0c;也可以導入定義好的txt文本形式的關…

實現模型貼圖的移動縮放旋轉

技術&#xff1a;threejscanvasfabric 效果圖&#xff1a; 原理&#xff1a;threejs中沒有局部貼圖的效果&#xff0c;只能通過map 的方式貼到模型上&#xff0c;所以說換一種方式來實現&#xff0c;通過canvasfabric來實現圖片的移動縮放旋轉&#xff0c;然后將整個畫布以map…

數據集 | 人臉公開數據集的介紹及下載地址

本文介紹了人臉相關算法的數據集。 1.人臉數據集詳情 1.1.Labeled Faces in the Wild (LFW) 論文 下載地址&#xff1a;LFW Face Database : Main (umass.edu) 是目前人臉識別的常用測試集&#xff0c;其中提供的人臉圖片均來源于生活中的自然場景&#xff0c;因此識別難度會…

DDR的拓撲與仿真

T型拓撲 vs Fly-by 由于T型拓撲在地址、命令和時鐘都是同時到達每個DDR芯片&#xff0c;所以同步的切換噪聲會疊加在一起&#xff0c;DDR越多這個信號上疊加的噪聲越大&#xff0c;T型拓撲的優點是地址、命令和時鐘都是同時到達&#xff0c;所以不需要做寫均衡Write leveling。…

Node.js 生成vue組件

在項目根目錄下創建 create.js /*** 腳本生成vue組件* 主要是利用node自帶的fs模塊操作文件的寫入* ===========================================* 準備步驟:* 1.輸入作者名* 2.輸入文件名* 3.輸入菜單名* 4.輸入文件地址* ============================================* 操…

【路徑規劃】基于A星算法實現機器人柵格地圖徑規劃附Matlab代碼

% 機器人柵格地圖路徑規劃(A*算法) % 假設你已經有了柵格地圖數據和起點終點坐標 % 柵格地圖數據 grid_map = your_grid_map_data; % 柵格地圖數據,0表示可行區域,1表示障礙物區域 % 起點和終點坐標 start = your_start_coordinates; % 起點坐標,格式為[x, y] goal = yo…

【3D->2D轉換(1)】LSS(提升,投放,捕捉)

Lift, Splat, Shoot 這是一個端到端架構&#xff0c;直接從任意數量的攝像頭數據提取給定圖像場景的鳥瞰圖表示。將每個圖像分別“提升&#xff08;lift&#xff09;”到每個攝像頭的視錐&#xff08;frustum&#xff09;&#xff0c;然后將所有視錐“投放&#xff08;splat&a…

AI助手崛起:開發者的新伙伴還是未來替代者?

你好&#xff0c;我是三橋君。 自從 ChatGPT 問市以來&#xff0c;AI 將取代開發者的聲音不絕于耳&#xff0c;至今還是互聯網異常火熱的問題。 在軟件開發領域&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;正在改變開發者的工作方式。無論是代碼生成、錯誤檢測還是…

【JavaWeb程序設計】JSP編程

目錄 一、編寫JSP頁面&#xff0c;在界面上顯示1-9&#xff0c;9個鏈接&#xff0c;單擊每個鏈接&#xff0c;能夠在另一個頁面打印該數字的平方。 1. 運行截圖 2. 第一個jsp頁面&#xff08;index.jsp&#xff09; 3. 第二個jsp頁面&#xff08;square.jsp&#xff09; 二…

RedHat運維-Linux存儲管理基礎1-添加分區、文件系統、持續性掛載

1. 假如當前系統上ls -alh /dev | grep ^b的結果如下所示&#xff0c;那么&#xff1a; [rhcerhel9 ~]$ ls -alh /dev | grep ^b brw-rw----. 1 root disk 253, 0 Jun 7 19:46 dm-0 brw-rw----. 1 root disk 253, 1 Jun 7 19:46 dm-1 brw-rw----. 1 root disk …

Arc for Windows 無法使用?一篇文章教會你!

&#x1f44b; 大家好&#xff0c;我是 Beast Cheng &#x1f4eb; 聯系我&#xff1a;458290771qq.com &#x1f331; 接合作、推廣…… 什么是Arc瀏覽器&#xff1f; Arc瀏覽器是The Browser Conpany使用Swift語言開發的一款瀏覽器&#xff0c;Arc瀏覽器由其漂亮的側邊欄聞名…

Python 異步編程介紹與代碼示例

Python 異步編程介紹與代碼示例 一、異步編程概述 異步編程是一種編程范式&#xff0c;它旨在處理那些需要等待I/O操作完成或執行耗時任務的情況。在傳統的同步編程中&#xff0c;代碼會按照順序逐行執行&#xff0c;直到遇到一個耗時操作&#xff0c;它會阻塞程序的執行直到…

Codeforces Round 903 (Div. 3)A~F

A.Dont Try to Count 輸入樣例&#xff1a; 12 1 5 a aaaaa 5 5 eforc force 2 5 ab ababa 3 5 aba ababa 4 3 babb bbb 5 1 aaaaa a 4 2 aabb ba 2 8 bk kbkbkbkb 12 2 fjdgmujlcont tf 2 2 aa aa 3 5 abb babba 1 19 m mmmmmmmmmmmmmmmmmmm輸出樣例&#xff1a; 3 1 2 -1 1 0…

1999-2022年企業持續綠色創新水平數據

企業持續綠色創新水平數據為研究者提供了評估企業在綠色技術領域創新持續性和能力的重要視角。以下是對企業持續綠色創新水平數據的介紹&#xff1a; 數據簡介 定義&#xff1a;企業持續綠色創新水平反映了企業在一定時期內綠色專利申請的持續性和創新能力。計算方法&#xf…

初識STM32:開發方式及環境

STM32的編程模型 假如使用C語言的方式寫了一段程序&#xff0c;這段程序首先會被燒錄到芯片當中&#xff08;Flash存儲器中&#xff09;&#xff0c;Flash存儲器中的程序會逐條的進入CPU里面去執行。 CPU相當于人的一個大腦&#xff0c;雖然能執行運算和執行指令&#xff0c;…

通信協議:常見的芯片內通信協議

相關閱讀 通信協議https://blog.csdn.net/weixin_45791458/category_12452508.html?spm1001.2014.3001.5482 本文將簡單介紹一些常見的芯片間通信協議&#xff0c;但不會涉及到協議的具體細節。 一、AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;…

MySQL之備份與恢復(七)

備份與恢復 文件系統快照 規劃LVM備份 LVM快照備份也是有開銷的。服務器寫到原始卷的越多&#xff0c;引發的額外開銷也越多。當服務器隨機修改許多不同塊時&#xff0c;磁頭需要需要自寫時復制空間來來回回尋址&#xff0c;并且將數據的老版本寫到寫時復制空間。從快照中讀…

刷題之多數元素(leetcode)

多數元素 哈希表解法&#xff1a; class Solution { public:/*int majorityElement(vector<int>& nums) {//map記錄元素出現的次數&#xff0c;遍歷map&#xff0c;求出出現次數最多的元素unordered_map<int,int>map;for(int i0;i<nums.size();i){map[nu…

最適合mysql5.6安裝的linux版本-實戰

文章目錄 一, 適合安裝mysql5.6的linu版本1. CentOS 72. Ubuntu 14.04 LTS (Trusty Tahr)3. Debian 8 (Jessie)4. Red Hat Enterprise Linux (RHEL) 7 二, 具體以Ubuntu 14.04 LTS (Trusty Tahr)為例安裝虛擬機安裝Ubuntu 14.04 LTS (Trusty Tahr) 自己弄安裝ssh(便于遠程訪問,…

前端八股文 對$nextTick的理解

$nexttick是什么? 獲取更新后的dom內容 為什么會有$nexttick ? vue的異步更新策略 (這也是vue的優化之一 要不然一修改數據就更新dom 會造成大量的dom更新 浪費性能) 這是因為 message &#xff08;data&#xff09;數據在發現變化的時候&#xff0c;vue 并不會立刻去更…