C++二分算法:最多可以參加的會議數目 II

本文涉及的基礎知識點

二分查找算法合集

本題其它解法

C++二分向量算法:最多可以參加的會議數目 II

題目

給你一個 events 數組,其中 events[i] = [startDayi, endDayi, valuei] ,表示第 i 個會議在 startDayi 天開始,第 endDayi 天結束,如果你參加這個會議,你能得到價值 valuei 。同時給你一個整數 k 表示你能參加的最多會議數目。
你同一時間只能參加一個會議。如果你選擇參加某個會議,那么你必須 完整 地參加完這個會議。會議結束日期是包含在會議內的,也就是說你不能同時參加一個開始日期與另一個結束日期相同的兩個會議。
請你返回能得到的會議價值 最大和 。
示例 1:
輸入:events = [[1,2,4],[3,4,3],[2,3,1]], k = 2
輸出:7
解釋:選擇綠色的活動會議 0 和 1,得到總價值和為 4 + 3 = 7 。
示例 2:
輸入:events = [[1,2,4],[3,4,3],[2,3,10]], k = 2
輸出:10
解釋:參加會議 2 ,得到價值和為 10 。
你沒法再參加別的會議了,因為跟會議 2 有重疊。你 不 需要參加滿 k 個會議。
示例 3:
輸入:events = [[1,1,1],[2,2,2],[3,3,3],[4,4,4]], k = 3
輸出:9
解釋:盡管會議互不重疊,你只能參加 3 個會議,所以選擇價值最大的 3 個會議。
**參數范圍:
1 <= k <= events.length
1 <= k * events.length <= 106
1 <= startDayi <= endDayi <= 109
1 <= valuei <= 106

分析

時間復雜度

時間復雜度O(knlogn),兩層循環。第一層循環循環k-1次,第二層循環循環n次。循環內部查找、插入、刪除O(logn)。

變量解釋

mPre 記錄的上一輪的完成情況,dp是當前輪的完成情況。鍵對應的是:結束時間,值對應的是:最大會議價值。如果key0 <= key1且value0 >= value1,那么key0會淘汰key1。能選取key1,一定能選取key0,而value0大于等于value1。淘汰后,值保持升序。鍵小的淘汰鍵大的。

代碼

核心代碼

template<class _Kty,class _Ty,bool bValueDdes,bool bOutSmallKey> 
class COrderValueMap 
{
public:void Add (_Kty iValue, _Ty iNum){if (bOutSmallKey){if (bValueDdes){AddOutSmall(iValue, iNum, std::less_equal<_Ty>(), std::greater_equal<_Ty>());}else{}}else {if (bValueDdes){AddNotOutSmall(iValue, iNum, std::greater_equal<_Ty>(), std::less_equal<_Ty>());}else{AddNotOutSmall(iValue, iNum, std::less_equal<_Ty>(), std::greater_equal<_Ty>());}}};template<class _Pr1, class _Pr2>void AddOutSmall(_Kty key, _Ty value, _Pr1 pr1, _Pr2 pr2){auto it = m_map.lower_bound(key);if ((m_map.end() != it) && pr1(it->second, value)){return;//被舊值淘汰}auto ij = it;while (it != m_map.begin()){--it;if (pr2(it->second, value)){it = m_map.erase(it);}}m_map[key] = value;}template<class _Pr1, class _Pr2>void AddNotOutSmall(_Kty key, _Ty value, _Pr1 pr1,_Pr2 pr2 ){auto it = m_map.upper_bound(key);if ((m_map.begin() != it) && pr1(std::prev(it)->second, value)){return;//被淘汰}auto ij = it;for (; (m_map.end() != ij) && pr2(ij->second, value); ++ij);m_map.erase(it, ij);m_map[key] = value;};std::map<_Kty, _Ty> m_map;
};class Solution {
public:int maxValue(vector<vector<int>>& events, int k) {COrderValueMap<int, int, true, false> mPre;for (const auto& v : events){mPre.Add(v[1], v[2]);}while (--k){COrderValueMap<int, int, true, false> dp;for (const auto& v : events){auto it = mPre.m_map.lower_bound(v[0]);int iNewValue = v[2];if (mPre.m_map.begin() != it){iNewValue += std::prev(it)->second;}dp.Add(v[1], iNewValue);}dp.m_map.swap(mPre.m_map);}return mPre.m_map.rbegin()->second;}	
};

測試用例

template <class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template <class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{vector<vector<int>> events;int k;int res;{Solution slu;events = { {1,2,4},{3,4,3},{2,3,1} };k = 2;res = slu.maxValue(events, k);Assert(res,7 );}{Solution slu;events = { {1,2,4},{3,4,3},{2,3,10} };k = 2;res = slu.maxValue(events, k);Assert(res, 10);}{Solution slu;events = { {1,1,1},{2,2,2},{3,3,3},{4,4,4} };k = 3;res = slu.maxValue(events, k);Assert(res, 9);}//CConsole::Out(res);}

優化版:第一輪不特殊處理

class Solution {
public:
int maxValue(vector<vector>& events, int k) {
COrderValueMap<int, int, true, false> mPre;
mPre.Add(0, 0);
while (k–)
{
COrderValueMap<int, int, true, false> dp;
for (const auto& v : events)
{
auto it = mPre.m_map.lower_bound(v[0]);
int iNewValue = v[2];
if (mPre.m_map.begin() != it)
{
iNewValue += std::prev(it)->second;
}
dp.Add(v[1], iNewValue);
}
dp.m_map.swap(mPre.m_map);
}
return mPre.m_map.rbegin()->second;
}
};

2023年2月舊代碼

class Solution {
public:
int maxValue(vector<vector>& events, int k) {
//dp[i] 已經完成i次會議后的最大值
vector vFinish(k + 1, -1);
vFinish[0] = 0;
std::map<int, vector> mDoing;
std::sort(events.begin(), events.end(), [](const vector& v1, const vector& v2)
{
return v1[0] < v2[0];
});
for (const auto& v : events)
{
while (mDoing.size() && mDoing.begin()->first < v[0])
{
vector& vDoing = mDoing.begin()->second;
for (int iK = 0; iK <= k; iK++)
{
vFinish[iK] = max(vDoing[iK], vFinish[iK]);
}
mDoing.erase(mDoing.begin());
}
vector& vDoing = mDoing[v[1]];
if (0 == vDoing.size())
{
vDoing.resize(k + 1, -1);
}
for (int iK = 0; iK <= k; iK++)
{
vDoing[iK] = max(vDoing[iK], vFinish[iK]);
if (iK > 0)
{
vDoing[iK] = max(vDoing[iK], vFinish[iK-1] + v[2] );
}
}
}
while (mDoing.size() )
{
vector& vDoing = mDoing.begin()->second;
for (int iK = 0; iK <= k; iK++)
{
vFinish[iK] = max(vDoing[iK], vFinish[iK]);
}
mDoing.erase(mDoing.begin());
}
return *std::max_element(vFinish.begin(), vFinish.end());
}
};

2023年9月舊代碼

class Solution {
public:
int maxValue(vector<vector>& events, int k) {
m_c = events.size();
vector indexs(m_c);
iota(indexs.begin(), indexs.end(), 0);
sort(indexs.begin(), indexs.end(), [&events](const int& i1, const int& i2)
{
return events[i1][0] < events[i2][0];
});
std::map<int,int> mEndValue;
mEndValue[-1] = 0;
for (int iK = 0; iK < k; iK++)
{
std::map<int, int> dp;
for (const auto& i : indexs)
{
auto it = mEndValue.lower_bound(events[i][0]);
const int iPre = (it == mEndValue.begin()) ? 0 : std::prev(it)->second;
const int iNew = iPre + events[i][2];
auto ij = dp.upper_bound(events[i][1]);
if ((ij != dp.begin()) && (std::prev(ij)->second >= iNew))
{
continue;//前面的數值大,再增意義
}
ij = dp.lower_bound(events[i][1]);
auto tmp = ij;
for (; (tmp != dp.end()) && (tmp->second <= iNew); ++tmp);
dp.erase(ij, tmp);
dp[events[i][1]] = iNew;
}
dp.swap(mEndValue);
}
int iMax = 0;
for (const auto& it : mEndValue)
{
iMax = max(iMax, it.second);
}
return iMax;
}
int m_c;
};

擴展閱讀

視頻課程

有效學習:明確的目標 及時的反饋 拉伸區(難度合適),可以先學簡單的課程,請移步CSDN學院,聽白銀講師(也就是鄙人)的講解。
https://edu.csdn.net/course/detail/38771

如何你想快

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

相關下載

想高屋建瓴的學習算法,請下載《喜缺全書算法冊》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想對大家說的話
聞缺陷則喜是一個美好的愿望,早發現問題,早修改問題,給老板節約錢。
子墨子言之:事無終始,無務多業。也就是我們常說的專業的人做專業的事。
如果程序是一條龍,那算法就是他的是睛

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

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

相關文章

如何在Ubuntu 20.04.6 LTS系統上運行Selenium自動化測試

文章目錄 寫在前面一、 環境準備1.1 安裝python31.1.1 使用APT安裝Python31.1.2 使用PPA安裝較新版本的Python31.1.3 從源代碼編譯安裝Python31.2 安裝pip31.3 安裝jdk1.4 安裝運行所需瀏覽器1.4 使用Git拉取自動化測試代碼/復制自動化測試代碼到Ubuntu 20.04.6 LTS二、安裝pip…

Let’s xrOS 一款讓你優先體驗社區創作者的 visionOS App工具

Let’s xrOS Apple Vision Pro 發布預示著空間計算時代的到來&#xff0c;讓科技愛好者和開發者開始思考如何在新的交互、系統和硬件上打造獨特的三維應用。 自 WWDC 2023 的發布會后&#xff0c;社交媒體上涌現了許多精美的 visionOS App 的效果圖和演示視頻&#xff0c;然而…

Rola詳解國外住宅IP代理選擇的8個方法,穩定的海外IP哪個靠譜?

一、國外住宅IP代理是什么&#xff1f; 代理服務器充當您和互聯網之間的網關。它是一個中間服務器&#xff0c;將最終用戶與他們瀏覽的網站分開。如果您使用國外代理IP&#xff0c;互聯網流量將通過國外代理服務器流向您請求的地址。然后&#xff0c;請求通過同一個代理服務器…

常見樹種(貴州省):014槭樹、梧桐、鵝掌楸、檫木、梓木、油桐、泡桐、川楝、麻楝

摘要&#xff1a;本專欄樹種介紹圖片來源于PPBC中國植物圖像庫&#xff08;下附網址&#xff09;&#xff0c;本文整理僅做交流學習使用&#xff0c;同時便于查找&#xff0c;如有侵權請聯系刪除。 圖片網址&#xff1a;PPBC中國植物圖像庫——最大的植物分類圖片庫 一、色木槭…

java--繼承快速入門

1.什么是繼承 java中提供了一個關鍵字extends&#xff0c;用這個關鍵字&#xff0c;可以讓一個類和另一個類建立其父子關系。 2.繼承的特點 子類能繼承父類的非私有成員(成員變量&#xff0c;成員方法)。 3.繼承后對象的創建 子類的對象是由子類、父類共同完成的。 4.繼承的…

基于IDEA+HTML+SpringBoot前后端分離電子商城

基于springboot的電子商城 項目介紹&#x1f481;&#x1f3fb; ?B2C 商家對客戶 ?C2B2C 客戶對商家對客戶 1.1.1 B2C 平臺運營方即商品的賣家 小米商城 ?商品 ?用戶 1.1.2 C2B2C 平臺運營方不賣商品&#xff08;也可以賣&#xff09; 賣家是平臺的用戶 買家也是平臺用戶 ?…

『C++成長記』C++入門—— 函數重載引用

&#x1f525;博客主頁&#xff1a;小王又困了 &#x1f4da;系列專欄&#xff1a;C &#x1f31f;人之為學&#xff0c;不日近則日退 ??感謝大家點贊&#x1f44d;收藏?評論?? 目錄 一、函數重載 &#x1f4d2;1.1函數重載的概念 &#x1f4d2;1.2函數重載的種類 …

基于51單片機音樂盒設計( proteus仿真+程序+原理圖+PCB+報告+講解視頻)

音樂盒 主要功能&#xff1a;仿真原理圖PCB圖程序設計&#xff1a;設計報告實物圖資料清單&#xff08;提供資料清單所有文件&#xff09;&#xff1a;資料下載鏈接&#xff1a; 基于51單片機音樂盒仿真設計( proteus仿真程序原理圖PCB報告講解視頻&#xff09; 仿真圖proteus …

Python實現交易策略評價指標-收益率

1.收益率的定義 收益率幾乎是所有投資者都會關注的一個指標&#xff0c;收益率的高低決定了投資策略的賺錢能力&#xff0c;常見關于收益率的指標如下&#xff1a; 持有期收益率 持有期收益率 期末投資權益 ? 期初投資權益 期初投資權益 持有期收益率 \frac {期末投資權益…

GeoTrust SSL數字安全證書介紹

一、GeoTrust OV證書的介紹 GeoTrust OV證書是由GeoTrust公司提供的SSL證書&#xff0c;它是一種支持OpenSSL的數字證書&#xff0c;具有更高的安全性和可信度。GeoTrust是全球領先的網絡安全解決方案提供商&#xff0c;為各類用戶提供SSL證書和信任管理服務。GeoTrust OV證書…

docker國內鏡像加速

創建或修改 /etc/docker/daemon.json 文件&#xff0c;修改為如下形式 {"registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn"] } Docker中國區官方鏡像htt…

51單片機應用從零開始(八)·循環語句(for循環、while 語句、do‐while 語句)

51單片機應用從零開始&#xff08;七&#xff09;循環語句&#xff08;if語句&#xff0c;swtich語句&#xff09;-CSDN博客 目錄 1. 用for 語句控制蜂鳴器鳴笛次數 2. 用while 語句控制 LED 3. 用 do‐while 語句控制 P0 口 8 位 LED 流水點亮 1. 用for 語句控制蜂鳴器鳴笛…

Kafka 控制器(controller)

Kafka 控制器&#xff08;controller&#xff09; 在kafka集群中 會存在一個或者多個broker&#xff08;一個服務器就是一個broker&#xff09;&#xff0c;其中有一個broker會被選舉為控制器 kafka controller &#xff0c;負責管理整個集群中所有副本、分區的狀態&#xff0…

多語言快速排序算法

快速排序是一種高效的排序算法&#xff0c;使用分治法策略。它的基本思想是&#xff1a;選擇一個元素作為“基準”&#xff08;pivot&#xff09;&#xff0c;重新排序數列&#xff0c;所有比基準值小的元素擺放在基準前面&#xff0c;所有比基準值大的擺在基準的后面。在這個分…

python內置模塊binascii,二進制數據和ASCII字符串之間進行轉換

一、簡介 binascii是Python標準庫中的一個模塊&#xff0c;提供了在二進制數據和ASCII字符串之間進行轉換的功能。它包含了一些用于處理二進制數據的函數&#xff0c;可以進行二進制數據的編碼、解碼和轉換。 二、方法 binascii.unhexlify(hexstr)&#xff1a;將十六進制表示…

事件循環機制及常見面試題

借鑒&#xff1a; 《Javascript 忍者秘籍》第二版&#xff0c;事件循環篇 面試 | JS 事件循環 event loop 經典面試題含答案 - 知乎 (zhihu.com) 概念 主棧隊列就是一個宏任務&#xff0c;每一個宏任務執行完就會執行宏任務中的微任務&#xff0c;直到微任務全部都執行完&a…

Python 使用XlsxWriter操作Excel

在數據處理和報告生成的領域中&#xff0c;Excel 文件一直是廣泛使用的標準格式。為了讓 Python 開發者能夠輕松創建和修改 Excel 文件&#xff0c;XlsxWriter 庫應運而生。XlsxWriter 是一個功能強大的 Python 模塊&#xff0c;專門用于生成 Microsoft Excel 2007及以上版本&a…

Vue3-provide和inject

作用和場景&#xff1a;頂層組件向任意的底層組件傳遞數據和方法&#xff0c;實現跨層組件通信 跨層傳遞普通數據&#xff1a; 1.頂層組件通過provide函數提供數據 2.底層組件通過inject函數獲取數據 既可以傳遞普通數據&#xff0c;也可以使用ref傳遞響應式數據&#xff08…

批量插入SQL 錯誤 [933] [42000]: ORA-00933: SQL 命令未正確結束

使用DBeaver向【oracle數據庫】插入大量數據 INSERT INTO Student(name,sex,age,address,birthday) VALUES(Nike,男,18,北京,2000-01-01) ,(Nike,男,18,北京,2000-01-01) ,(Nike,女,18,北京,2000-01-01) ,(Nike,女,18,北京,2000-01-01) ,(Nike,男,18,北京,2000-01-01) ,(Nike…

使用Arrays.Sort并定制Comparator排序解決合并區間

合并區間-力扣算法題56題 以數組 intervals 表示若干個區間的集合&#xff0c;其中單個區間為 intervals[i] [starti, endi] 。請你合并所有重疊的區間&#xff0c;并返回 一個不重疊的區間數組&#xff0c;該數組需恰好覆蓋輸入中的所有區間 。 示例 1&#xff1a; 輸入&am…