(1)問題描述:假設要在足夠多的會場里安排一批活動,並希望使用盡可能少的會場。前提每個活動都有開始和結束時間,一個會場中多個活動不能交叉進行,只能按次序進行,設計一個有效的貪心算法進行安排。
(2)算法設計:對於給定的 activities 個帶安排的活動,計算使用最少會場的時間表;
(3)數據輸入:第一行輸入待安排的活動數量 activities。接下來 activities 行中,每一行有 2 個整數,分別表示 activities 個待安排的活動的開始和結束時間;
(4)思想:記錄每個活動的開始和結束時間,按照升序排列,遍歷活動開始【START】和結束【FINISHED】標識,遇到 START,加 1,遇到 FINISHED,減 1,然后遍歷活動標識數組,找出最大值即為最少會場數量;
(5)代碼展示:
public class MeetingArrange { /** * 會場開始結束標識 */ private static final String START = "start"; private static final String FINISHED = "finished"; /** * 會場安排的活動數量 */ private static Integer activities = 0; /** * 記錄當前最少的會場個數 */ private static Integer minMettings = 0; /** * 記錄當前會場的數量 */ private static Integer[] nowMettingCount; /** * 活動安排開始結束時間數組 */ private static Integer[] startAndFinishedTime; /** * 活動安排開始結束標識 */ private static String[] flag; /** * 初始化數據 */ private static void initData() { Scanner input = new Scanner(System.in); System.out.println("請輸入安排的活動數量:"); activities = input.nextInt(); System.out.println("請輸入每個活動開始和結束時間:"); startAndFinishedTime = new Integer[activities * 2]; flag = new String[activities * 2]; nowMettingCount = new Integer[flag.length]; for (int i = 0; i < activities * 2; i = i + 2) { startAndFinishedTime[i] = input.nextInt(); // 活動開始時間 startAndFinishedTime[i + 1] = input.nextInt(); // 活動結束時間 flag[i] = START; // 活動開始標識 flag[i + 1] = FINISHED; // 活動結束標識 nowMettingCount[i] = 0; // 初始化當前會場數量為 0 } } /** * 活動起始、結束時間數組升序排列 */ private static void sortAsc() { Integer temp; Integer change = 1; String str; for (int i = 0; i < startAndFinishedTime.length - 1 && change == 1; i++) { change = 0; for (int j = 0; j < startAndFinishedTime.length - i - 1; j++) { if (startAndFinishedTime[j] > startAndFinishedTime[j + 1]) { // 活動開始和結束時間交換 temp = startAndFinishedTime[j]; startAndFinishedTime[j] = startAndFinishedTime[j + 1]; startAndFinishedTime[j + 1] = temp; // 活動開始和結束標識交換 str = flag[j]; flag[j] = flag[j + 1]; flag[j + 1] = str; change = 1; } } } } /** * 統計最少的會場數量 * 思想:遇到 START,當前會場數量加 1,遇到 FINISHED,當前會場數量減 1;然后遍歷當前會場數量數組,取最大值即為最少會場數 */ private static Integer countMinMettings() { for (int i = 0; i < flag.length; i++) { if (flag[i].equals(START)) { minMettings++; } else { minMettings--; } nowMettingCount[i] = minMettings; } // 找出最少的會場數量 return Stream.of(nowMettingCount).max(Comparator.comparingInt(o -> o)).get(); } public static void main(String[] args) { // 初始化數據 initData(); // 升序 sortAsc(); // Stream.of(startAndFinishedTime).forEach(element -> System.out.print(element + " ")); // 統計最少的會場數量 Integer min = countMinMettings(); System.out.println("最少的會場數量為:" + min); } }
(6)輸入輸出:
請輸入安排的活動數量: 5 請輸入每個活動開始和結束時間: 1 23 12 28 25 35 27 80 36 50 最少的會場數量為:3
(7)總結:會場安排完全闡釋了貪心算法的核心思想,統計出多個局部最優解,在此局部最優解的集合中,選擇一個整體的最優解;