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

โปรแกรมหาค่าสูงสุดที่ได้จากการใส่ของในกระเป๋า (Knapsack) ใน Python

ได้รับ weights, values ความยาวเท่ากัน และ capacity, count สามารถเลือกของได้สูงสุด count ชิ้น น้ำหนักรวม ≤ capacity แต่ละชิ้นเลือกได้สูงสุด 1 ครั้ง หา value สูงสุด

ตัวอย่าง

weights = [2, 2, 4, 6], values = [15, 15, 20, 35]

capacity = 8, count = 3 → Output: 50 (เลือก 3 ชิ้นแรก น้ำหนัก 2+2+4=8, value 15+15+20=50)

แนวทางแก้ปัญหา

เป็น 0/1 Knapsack พร้อมข้อจำกัดจำนวนชิ้น ใช้ Memoized Recursion (Top-down DP):

  • State: dp(i, cap_left, cnt_left) = value สูงสุดจาก item i เป็นต้นไป
  • Base: i == n หรือ cnt_left == 0 → 0
  • Transition: ไม่เลือก item i, หรือ เลือก (ถ้าน้ำหนักพอ)

การใช้งาน (Python)

from functools import lru_cache

class Solution:
    def solve(self, weights, values, capacity, count):
        items = list(zip(weights, values))
        n = len(items)
        
        @lru_cache(None)
        def dp(i, cap, cnt):
            if i == n or cnt == 0:
                return 0
            w, v = items[i]
            # ไม่เลือก
            ans = dp(i + 1, cap, cnt)
            # เลือก
            if cap >= w:
                ans = max(ans, dp(i + 1, cap - w, cnt - 1) + v)
            return ans
        
        return dp(0, capacity, count)

# ทดสอบ
ob = Solution()
weights = [2, 2, 4, 6]
values = [15, 15, 20, 35]
print(ob.solve(weights, values, 8, 3))  # Output: 50

ความซับซ้อน

  • Time Complexity: O(N × capacity × count)
  • Space Complexity: O(N × capacity × count)

สำหรับค่าใหญ่ควรใช้ Bottom-up DP หรือปรับปรุงพื้นที่หน่วยความจำ