【牛客刷題】活動安排

文章目錄

  • 一、題目介紹
  • 二、解題思路
    • 2.1 核心問題
    • 2.2 貪心策略
    • 2.3 正確性證明
  • 三、算法分析
    • 3.1 為什么按結束時間排序?
    • 3.2 復雜度分析
    • 3.3 算法流程圖解
      • 3.3.1 流程圖說明
      • 3.3.2 關鍵步驟說明
  • 四、模擬演練
  • 五、完整代碼

一、題目介紹

在這里插入圖片描述

  • 活動安排

題目描述
給定 nnn 個活動,每個活動的時間區間為 [ai,bi)[a_i, b_i)[ai?,bi?)(左閉右開)。要求選擇盡可能多的活動,使得這些活動的時間區間互不重疊。

輸入描述

  • 第一行:整數 nnn1≤n≤2×1051 \leq n \leq 2 \times 10^51n2×105),表示活動數量
  • 后續 nnn 行:每行兩個整數 ai,bia_i, b_iai?,bi?0≤ai<bi≤1090 \leq a_i < b_i \leq 10^90ai?<bi?109

輸出描述

  • 一個整數,表示最多可選擇的活動數

示例

  • 輸入:
    3
    1 4
    1 3
    3 5
    
  • 輸出:2
  • 說明:可選擇活動 [1,3)[1,3)[1,3)[3,5)[3,5)[3,5)

二、解題思路

2.1 核心問題

在多個時間區間中選出最大互斥子集——經典的區間調度問題

2.2 貪心策略

  1. 排序策略

    • 將所有活動按結束時間升序排序
    • 結束時間相同時,開始時間不影響結果(可任意排序)
  2. 選擇策略

    • 初始化選擇第一個活動(最早結束)
    • 遍歷后續活動:
      • 若當前活動的開始時間 ≥\geq 上一個選中活動的結束時間
      • 則選擇該活動,并更新記錄點

2.3 正確性證明

  • 貪心選擇性:最早結束的活動一定在某個最優解中
  • 最優子結構:選擇最早結束活動后,剩余問題仍是相同結構的子問題
  • 反證法:若存在更優解,其第一個活動結束時間一定不早于貪心選擇的活動

三、算法分析

3.1 為什么按結束時間排序?

排序方式反例問題原因
按開始時間排序
[1,5]
[2,3]
[4,6]
[1,5] 后無法選其他
按區間長度排序
[1,4]
[2,3]
[3,5]
選最短 [2,3] 后只能再選一個
按結束時間排序無反例保證最大化剩余時間

3.2 復雜度分析

  • 時間復雜度O(nlog?n)O(n \log n)O(nlogn)
    • 排序:O(nlog?n)O(n \log n)O(nlogn)(占主導)
    • 遍歷:O(n)O(n)O(n)
  • 空間復雜度O(n)O(n)O(n)
    • 存儲 nnn 個活動對象

3.3 算法流程圖解

flowchart TDA[開始] --> B[讀取活動數量n]B --> C[創建空活動列表]C --> D[循環讀取n個活動]D --> E[存儲活動到列表]E --> F{是否讀完n個活動?}F -- 否 --> DF -- 是 --> G[按結束時間升序排序]G --> H[初始化:count=0, lastEnd=-1]H --> I[遍歷排序后活動列表]I --> J{當前活動開始時間 ≥ lastEnd?}J -- 是 --> K[count++,更新lastEnd=當前結束時間]J -- 否 --> L[跳過該活動]K --> M{是否還有活動?}L --> MM -- 是 --> IM -- 否 --> N[輸出count]N --> O[結束]

在這里插入圖片描述

3.3.1 流程圖說明

  1. 數據讀取階段

    • 讀取活動數量 n
    • 循環讀取 n 個活動的時間區間
    • 存儲在 ArrayList
  2. 排序階段

    • 使用自定義比較器 ActivityComparator
    • 按結束時間升序排序(最早結束的在前)
  3. 貪心選擇階段

    flowchart LRP[lastEnd初始值-1] --> Q{遍歷活動}Q --> R[活動A: start≥lastEnd?]R -- 是 --> S[選擇A, count+1, lastEnd=A.end]R -- 否 --> T[跳過A]S --> U{繼續遍歷}T --> U
    

在這里插入圖片描述

  1. 選擇邏輯示例(輸入 [[1,4], [1,3], [3,5]]):
    flowchart TBsubgraph 排序后A1[活動2: 1-3] --> A2[活動1: 1-4] --> A3[活動3: 3-5]endA1 --> B1{1 ≥ -1?} -- 是 --> C1[選擇, count=1, lastEnd=3]C1 --> A2A2 --> B2{1 ≥ 3?} -- 否 --> C2[跳過]C2 --> A3A3 --> B3{3 ≥ 3?} -- 是 --> C3[選擇, count=2, lastEnd=5]
    

在這里插入圖片描述

3.3.2 關鍵步驟說明

  1. 排序意義

    • 結束時間最早的活動優先被選擇
    • 為后續活動留下最大時間窗口
  2. lastEnd初始值-1的作用

    • 確保第一個活動總是被選擇
    • 數學上滿足:任意開始時間 ≥ -1
  3. 選擇條件 start ≥ lastEnd

    • 嚴格保證活動時間不重疊
    • 充分利用左閉右開區間特性([1,3)[3,5) 可銜接)

此流程圖清晰展示了貪心算法的核心思想:通過結束時間排序最大化剩余時間窗口,通過順序遍歷實現高效選擇

四、模擬演練

輸入數據

3
1 4
1 3
3 5

執行流程

  1. 排序階段(按結束時間升序):

    原始順序開始時間結束時間
    活動114
    活動213
    活動335

    ↓ 排序后 ↓

    新順序開始時間結束時間
    活動213
    活動114
    活動335
  2. 選擇階段

    當前活動開始時間結束時間上一活動結束時間是否選擇已選活動數更新結束時間
    活動213-1 (初始)?13
    活動1143?(1 < 3)13
    活動3353?(3 ≥ 3)25
  3. 輸出結果:2

邊界測試

  • 全重疊活動
    輸入:[1,2), [1,2), [1,2)
    輸出:1(只能選一個)

  • 大范圍數據
    輸入:2×1052 \times 10^52×105[i,i+1)[i, i+1)[i,i+1) 區間
    輸出:2×1052 \times 10^52×105(所有活動互不重疊)

五、完整代碼

import java.util.*;/*** 活動類:表示一個活動的時間區間 [startTime, endTime)*/
class Activity {int startTime;  // 活動開始時間int endTime;    // 活動結束時間(不包含)// 構造函數Activity(int startTime, int endTime) {this.startTime = startTime;this.endTime = endTime;}
}/*** 活動比較器:按結束時間升序排序* 為什么按結束時間排序?因為結束時間決定了活動占用時間段的長度*/
class ActivityComparator implements Comparator<Activity> {@Overridepublic int compare(Activity a, Activity b) {// 按結束時間從小到大排序:最早結束的排前面return a.endTime - b.endTime;}
}public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 1. 讀取活動數量int n = in.nextInt();// 2. 創建活動列表并存儲所有活動List<Activity> activities = new ArrayList<>();for (int i = 0; i < n; i++) {int startTime = in.nextInt();int endTime = in.nextInt();activities.add(new Activity(startTime, endTime));}// 3. 關鍵步驟:按結束時間升序排序(貪心算法的核心)Collections.sort(activities, new ActivityComparator());// 4. 貪心選擇過程int count = 0;          // 記錄可安排的活動數量int lastEndTime = -1;   // 上一個被選中活動的結束時間(初始化為-1,表示尚未選擇任何活動)for (Activity activity : activities) {// 如果當前活動開始時間 ≥ 上一個活動的結束時間(說明時間不重疊)if (activity.startTime >= lastEndTime) {count++;  // 選擇不重疊的活動lastEndTime = activity.endTime;  // 更新最后一個活動的結束時間}}// 5. 輸出結果System.out.println(count);}
}

關鍵優化點

  1. 結束時間排序
    Collections.sort(activities, (a, b) -> a.endTime - b.endTime);
    
  2. 貪心選擇
    if (act.startTime >= lastEnd) {count++;lastEnd = act.endTime;
    }
    

為什么不用優先隊列?

  • 排序后只需一次線性遍歷,復雜度 O(n)O(n)O(n)
  • 優先隊列 O(nlog?n)O(n \log n)O(nlogn) 的插入/刪除反而增加開銷

通過結束時間排序+貪心遍歷,高效解決大規模區間調度問題

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

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

相關文章

第1講:C語言常見概念

目錄 一、什么是C語言&#xff1f; 二、C語言的歷史與成就 三、編譯器選擇&#xff08;VS2022&#xff09; 1、編譯與鏈接 2、編譯器對比 3、VS2022的優缺點 四、VS項目與源文件、頭文件介紹 五、第一個C語言程序 六、main函數 七、printf和庫函數 八、關鍵字介紹 …

WinUI3入門18:從APP打開商店鏈接以及實現內購

初級代碼游戲的專欄介紹與文章目錄-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代碼都將會位于ctfc庫中。已經放入庫中我會指出在庫中的位置。 這些代碼大部分以Linux為目標但部分代碼是純C的&#xff0c;可以在任何平臺上使用。 源碼指引&#xff1a;github源…

BI布局拖拽 (1) 深入react-gird-layout源碼

因為有個拖拉拽的需求&#xff0c;類似于quickBi那樣的效果。在網上調研了一下發現react-grid-layout實現效果類似&#xff0c;但其也有局限性&#xff0c;比如不支持嵌套&#xff0c;不支持在多個gridLyaout之間互相拖拽。 要求&#xff1a;基于react-grid-layout的思路&#…

CentOS環境搭建-快速升級G++版本

在CentOS環境中快速升級G編譯器版本&#xff0c;對于追求最新語言特性的開發者來說至關重要。由于CentOS默認的軟件倉庫可能不提供G的最新版本&#xff0c;我們通常需要借助第三方軟件源&#xff0c;如Developer Toolset或使用Spack等包管理器來完成這一任務。下面將詳細介紹兩…

分布式接口冪等性的演進和最佳實踐,含springBoot 實現(Java版本)

一、背景&#xff1a;為什么需要冪等性 在微服務、分布式架構下&#xff0c;網絡不可靠、請求重試機制&#xff08;如前端超時重發、客戶端重發、網關重試、消息消費失敗重試等&#xff09;會帶來重復請求&#xff0c;如果接口沒有冪等性&#xff0c;可能導致&#xff1a; 重復…

OGRE 3D----6. 背景圖片渲染實現詳解

1. 背景圖片渲染原理 1.1 渲染隊列機制 Ogre3D 使用渲染隊列(Render Queue)來控制對象的渲染順序。背景圖片需要在所有其他對象之前渲染,因此我們將其設置為 RENDER_QUEUE_BACKGROUND。 1.2 視圖變換控制 為了讓背景圖片始終保持在場景的最遠處,我們需要: 使用單位投影…

K線連續漲跌統計與分析工具

K線連續漲跌統計與分析工具 1. 概述 本工具是一個用于分析金融時間序列數據(特別是K線數據)的Python腳本,主要功能是統計連續n根同方向K線后,第n+1根K線的漲跌情況。該工具不僅提供統計分析功能,還支持圖形化標記以驗證結果,幫助交易者和量化分析師識別市場中的特定模式…

jQuery EasyUI 簡介

jQuery EasyUI 簡介 引言 隨著互聯網技術的飛速發展,前端開發變得越來越重要。jQuery EasyUI 作為一款流行的前端UI框架,極大地簡化了前端開發的工作流程,提高了開發效率。本文將詳細介紹 jQuery EasyUI 的起源、特點、使用方法以及在實際項目中的應用。 一、jQuery Easy…

《測試開發:從技術角度提升測試效率與質量》

測試開發的核心工作內容與職責解析 一、測試開發的定位與核心價值 測試開發&#xff08;Test Development&#xff0c;簡稱 TestDev 或 SDET&#xff09;是融合軟件開發能力與測試工程思維的復合型崗位&#xff0c;不同于傳統測試工程師&#xff0c;其核心目標是通過技術手段提…

20250710解決KickPi的K7開發板刷機之后出現DDR異常:ch:1 dq0 fail,write:0x1,read:0x20300

20250710解決KickPi的K7開發板刷機之后出現DDR異常&#xff1a;ch:1 dq0 fail,write:0x1,read:0x20300 2025/7/10 20:36[BEGIN] 2025/7/10 19:29:03 /DDR 2f85f4b2d4 cym 25/03/04-14:38.55,fwver: v1.09 In ch0 ttot10 ch0 ttot10 ch1 ttot10 ch0 ttot18 LPDDR4, 2112MHz chan…

Ansible:強大的自動部署工具

文章目錄零、Ansible介紹一、安裝 ansible二、配置SSH密鑰1.檢查密鑰是否存在2.兩邊的機器要互相有對方的密鑰三、自動部署1.傳輸文件(1)inventory.ini(2)sync_blt.yml(3)執行命令2.安裝軟件(1)inventory.ini(2)install_efvs.yml(3)執行命令零、Ansible介紹 Ansible 是一個開源…

Nacos的基本功能以及使用Feign進行微服務間的通信

Nacos是Dynamic Naming and Configuration Service的縮寫。What’s Nacos? 下面結合SpringBoot項目&#xff0c;為你介紹Nacos的基本功能以及如何使用Feign進行微服務間的通信。 一、Nacos的基本功能 Nacos是阿里巴巴開源的一個更易于構建云原生應用的動態服務發現、配置管…

C1編譯器和C2編譯器Test01

在HotSpot VM中內嵌有兩個JIT編譯器&#xff0c;分別為Client Compiler和Server Compiler&#xff0c;通常簡稱為C1編譯器和C2編譯器。開發人員可以通過如下命令顯式指定JVM在運行時到底使用哪一種即時編譯器。(1)-client&#xff1a;指定JVM運行在Client模式下&#xff0c;并使…

MongoDB與Spring Boot完整使用指南

目錄 1. MongoDB基礎概念 什么是MongoDB? 核心概念對比 文檔結構示例 2. MongoDB的特點與優勢 主要特點 適用場景 3. MongoDB基本操作 基本CRUD操作 插入文檔 查詢文檔 更新文檔 刪除文檔 4. Spring Boot集成MongoDB 步驟1:添加依賴 步驟2:配置數據庫連接 …

swift開發,關于應用、頁面、視圖的生命周期

目錄一、應用生命周期&#xff08;App Lifecycle&#xff09;UIKit (AppDelegate)SwiftUI (使用 ScenePhase)二、頁面生命周期&#xff08;ViewController Lifecycle&#xff09;三、視圖生命周期&#xff08;UIView Lifecycle&#xff09;四、SwiftUI 視圖生命周期五、關鍵對比…

借助HarmonyOS SDK,《NBA巔峰對決》實現“分鐘級啟動”到“秒級進場”

《NBA巔峰對決》是由望塵科技推出的國內首個真實還原5V5王朝模式的操作籃球手游&#xff0c;提供流暢操作手感和真實籃球賽場體驗。豐富的玩法在為玩家帶來高質游戲體驗的同時&#xff0c;間接帶來了啟動流程冗長的問題&#xff0c;資源更新階段的等待感尤為突出。 “我們發現&…

HT-LINK ICE:海速芯32Gbps信號調理芯片,40dB補償+國產自主,打破高速互聯瓶頸!

HT-LINK ICE&#xff08;TENX海速芯&#xff09;產品解析與推廣文案一、產品定位HT-LINK ICE是TENX海速芯推出的高速信號調理芯片&#xff0c;專為PCIe 5.0/6.0、USB4、Thunderbolt等超高速接口設計&#xff0c;提供信號完整性增強和時鐘恢復功能&#xff0c;適用于數據中心、A…

深入剖析 ADL:C++ 中的依賴查找機制及其編譯錯誤案例分析

一、ADL 的定義與背景&#xff08;一&#xff09;ADL 的定義ADL&#xff08;Argument-Dependent Lookup&#xff0c;依賴查找&#xff09;是 C 中一種特殊的名稱查找機制&#xff0c;用于在調用函數時&#xff0c;根據函數參數的類型來確定查找的命名空間范圍。ADL 的核心思想是…

【科研繪圖系列】R語言繪制相關系數圖

文章目錄 介紹加載R包數據下載導入數據數據預處理畫圖系統信息參考介紹 【科研繪圖系列】R語言繪制相關系數圖 加載R包 library(vegan) library(dplyr)# install.packages("./RVisulizationData/003.mantel test/ggcor_0.9.8.1.tar.gz", repos = NULL, type = &quo…

pharokka phold--快速噬菌體注釋工具

pharokka是一款專用于噬菌體基因組及宏基因組的快速標準化注釋工具。PS.仍在積極更新中&#xff0c;最近一次更新是在今年6.20。 若需對細菌基因組進行快速標準化注釋&#xff0c;建議使用Bakta。啟發pharokka開發及命名的Prokka也是優秀選擇&#xff0c;但Bakta實為Prokka的卓…