Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

โปรแกรมจัดตารางงาน (Task Scheduling) ให้เวลาน้อยที่สุด พร้อม Cooldown (Python)

ปัญหา

กำหนด tasks list (ตัวเลข = task type) และ cooldown k
แต่ละ task ใช้ 1 นาที ต้องรอ k นาทีระหว่าง task ประเภทเดียวกัน
หาเวลาน้อยที่สุดทำให้เสร็จทั้งหมด

ตัวอย่าง: tasks=[2,2,2,3,3,2], k=1 → 7 นาที
Optimal: [2, 3, 2, 3, 2, WAIT, 2]

วิธีแก้: Greedy + Max Heap (Priority Queue)

ทุกๆ รอบ เลือก task ที่เหลือมากที่สุด (most frequent) จนกว่า cooldown จะหมด

อัลกอริทึม

  1. นับความถี่แต่ละ task → Counter
  2. วนจนกว่า Counter ว่าง:
    • ดึง (k+1) task ที่ frequent ที่สุด
    • ลด count แต่ละตัวลง 1, ลบออกถ้าเหลือ 0
    • เพิ่มเวลา k+1
  3. ปรับผลลัพธ์สุดท้าย: ans + last_size - (k+1)

โค้ด Python

from collections import Counter

class Solution:
    def solve(self, nums, k):
        c = Counter(nums)
        ans = 0
        last_size = 0
        
        while c:
            last_size = len(c)
            for x, _ in c.most_common(k + 1):
                c[x] -= 1
                if c[x] == 0:
                    del c[x]
            ans += k + 1
        
        return ans + last_size - (k + 1)

# ทดสอบ
ob = Solution()
print(ob.solve([2, 2, 2, 3, 3, 2], 1))  # 7
print(ob.solve([1, 1, 1, 1], 2))        # 10 (1, _, _, 1, _, _, 1, _, _, 1)
print(ob.solve([1, 2, 3], 2))           # 3 (no cooldown needed)

ความซับซ้อน

  • Time: O(n log m) - m = unique tasks, most_common ใช้ heap
  • Space: O(m) - counter storage

การทำงานตัวอย่าง [2,2,2,3,3,2], k=1

Round 1: c={2:4, 3:2}, most_common(2)=[(2,4),(3,2)]
  Process 2,3 → c={2:3, 3:1}, ans=2
Round 2: most_common(2)=[(2,3),(3,1)]
  Process 2,3 → c={2:2}, ans=4
Round 3: most_common(2)=[(2,2)]
  Process 2 → c={2:1}, ans=6
Round 4: most_common(2)=[(2,1)]
  Process 2 → c={}, last_size=1, ans=8
Return: 8 + 1 - 2 = 7

ความสัมพันธ์กับ LeetCode 621

นี่คือโจทย์ "Task Scheduler" (LeetCode 621) - รูปแบบคลาสสิกของ greedy scheduling