แจกแจงเซตย่อยด้วยบิตมาสก์
วนผ่านเซตย่อยทั้งหมดด้วยจำนวนเต็ม
แจกแจงเซตย่อยด้วยบิตมาสก์ เป็นบทเรียน Competitive Programming Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Competitive Programming Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Competitive Programming Academy มีบทเรียนทั้งหมด 4 บทเรียน
เซตย่อยในรูปตัวเลข
เซตย่อยทุกเซตของสิ่งของ n ชิ้นสามารถจับคู่กับจำนวนเต็มเพียงหนึ่งจำนวน นับจาก 0 ขึ้นไป แล้วบิตของแต่ละจำนวนจะเลือกว่าสิ่งของตัวใดอยู่ในเซตย่อย 🙂
มีเซตย่อยกี่เซต
เซตที่มีสมาชิกจำนวน n รายการมีสับเซต 2^n ชุด ดังนั้นการวนค่าจำนวนเต็มตั้งแต่ 0 ถึง 2^n ลบ 1 จะเยี่ยมชมสับเซตแต่ละชุดครบหนึ่งครั้งพอดี
for mask in range(1 << n):
pass # mask is one subset1 << n คือจำนวน
การเลื่อน 1 << n มีค่าเท่ากับ 2 ยกกำลัง n จึงเป็นวิธีเขียนขอบเขตบนของลูปสับเซตที่กระชับและรวดเร็ว
อ่านบิต i
หากต้องการตรวจว่าสมาชิก i อยู่ในสับเซตหรือไม่ ให้ตรวจสอบ บิต ของสมาชิกนั้นด้วยมาสก์และ 1 ที่เลื่อนไปทางซ้าย i ตำแหน่ง ผลลัพธ์ที่ไม่ใช่ศูนย์หมายความว่าสมาชิกนั้นถูกรวมอยู่ด้วย
if mask & (1 << i):
take(items[i])สร้างรายการที่เลือก
ตรวจดูแต่ละตำแหน่งบิต แล้วรวบรวมสมาชิกที่มี บิต เป็น 1 วิธีนี้จะแปลงมาสก์หนึ่งค่าให้เป็นสับเซตจริงที่มาสก์นั้นแทนอยู่
chosen = [items[i] for i in range(n) if mask & (1 << i)]เซตว่างและเซตเต็ม
มาสก์ 0 คือสับเซตว่าง ส่วนมาสก์ที่มีบิตเป็น 1 ทั้งหมดคือเซตเต็ม ทั้งสองกรณีเกิดขึ้นได้โดยอัตโนมัติ เพราะลูปของคุณครอบคลุมค่าทุกค่า
หาผลรวมของสับเซต
ภายในลูป ให้นำสมาชิกที่เลือกมาบวกกันเพื่อให้คะแนนแต่ละสับเซต นี่คือหัวใจของวิธีแก้ปัญหาแบบ ลองทุกกรณี ขนาดเล็กจำนวนมาก
total = sum(v[i] for i in range(n) if mask & (1 << i))นับบิตที่เป็น 1
จำนวนสมาชิกที่เลือกจะเท่ากับจำนวนบิตที่เป็น 1 ของมาสก์ ใน Python, bin(mask).count('1') จะให้ค่านี้ได้ทันที
size = bin(mask).count("1")ระวังขีดจำกัด
เนื่องจากมีสับเซตจำนวน 2^n ชุด เทคนิคนี้จึงเหมาะกับค่า n ขนาดเล็กเท่านั้น โดยทั่วไป n ประมาณ 20 ถือเป็นขีดสูงสุดที่ใช้งานได้จริงสำหรับการไล่ตรวจทุกกรณี
เหตุใดมาสก์บิตจึงเหนือกว่า
ลูปจำนวนเต็มเพียงลูปเดียวใช้แทนลูปซ้อนที่ยุ่งยากได้ และการดำเนินการระดับบิตก็ รวดเร็ว โค้ดจึงสั้น ชัดเจน และทดสอบได้ง่าย
รูปแบบที่นำกลับมาใช้ได้
วนลูปผ่าน มาสก์ ถอดรหัสบิตของมัน ให้คะแนนสับเซต แล้วเก็บคำตอบที่ดีที่สุด จดจำโครงแบบนี้ไว้ แล้วปัญหาเกี่ยวกับสับเซตจำนวนมากจะกลายเป็นงานที่ทำได้เป็นขั้นตอน
ตรวจสอบอย่างรวดเร็ว
คุณต้องการตรวจว่าสมาชิก i ถูกรวมอยู่ในสับเซตที่เข้ารหัสด้วยมาสก์หรือไม่
สรุป
วน มาสก์ ตั้งแต่ 0 ถึง 2^n ลบ 1 อ่านบิตด้วยมาสก์และ 1 ที่เลื่อนไปทางซ้าย แล้วให้คะแนนแต่ละสับเซต นี่คือวิธีลองทุกกรณีที่กระชับสำหรับค่า n ขนาดเล็ก 🚀
คำถามที่พบบ่อย
บทเรียน “แจกแจงเซตย่อยด้วยบิตมาสก์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “แจกแจงเซตย่อยด้วยบิตมาสก์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Competitive Programming Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Competitive Programming Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “แจกแจงเซตย่อยด้วยบิตมาสก์”
วนผ่านเซตย่อยทั้งหมดด้วยจำนวนเต็ม คุณปฏิบัติ Competitive Programming Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Competitive Programming Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Competitive Programming Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “แจกแจงเซตย่อยด้วยบิตมาสก์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Competitive Programming Academy นี้ได้ไหม
ได้ บทเรียน Competitive Programming Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การลองทุกกรณีเป็นกลยุทธ์ที่ใช้ได้
- แจกแจงด้วย itertools
- แจกแจงเซตย่อยด้วยบิตมาสก์
- ลดพื้นที่ค้นหาอย่างชาญฉลาด