• 14 min

โจทย์ข้อ equipped จาก programming.in.th

ของแต่ละชิ้นก็ใช้งานได้ไม่เหมือนกัน แถมยังแพงอีกต่างหาก มาเลือกซื้ออุปกรณ์ให้ทำงานได้ทุกประเภทในราคาที่น้อยที่สุดกันเถอะ!

เป็ดไอคอนของเรื่องเล่าชาวอัลกอ Practical Algorithms
Practical Algorithms: เรื่องเล่าชาวอัลกอ
เพจที่อยากให้คนไทยมีเนื้อหาอัลกอริทึมดีๆ ให้ได้อ่านกัน
เป็ดชาวอัลกอยืนอยู่บนบันไดช่าง และมีเครื่องมือรายล้อมอยู่หลายชิ้น

โจทย์

ความยาก ★★★☆☆

มีของทั้งหมด NN ชิ้น แต่ละชิ้นมีราคา wiw_i (wiw_i ไม่เกิน 10000) และมีงานทั้งหมด KK​ ประเภท (KK​ ไม่เกิน 8) ของแต่ละชิ้นจะบอกว่าสามารถใช้ทำงานประเภทไหนได้บ้าง และทำได้ไม่จำกัดครั้ง

คุณต้องการจะซื้อของทั้งหมดกี่ชิ้นก็ได้ให้ทำงานได้ทั้ง KK ประเภท ถามว่าราคาน้อยที่สุดจากการเลือกซื้อของคือเท่าไหร่เพื่อให้ทำงานได้ครบ

ข้อมูลนำเข้า

บรรทัดแรก : รับจำนวน NN และ KK แทนจำนวนอุปกรณ์และงานตามลำดับโดยที่ 1N10,0001\leq N \leq 10,000 และ 1K81\leq K \leq 8

บรรทัดที่ 2 ถึง N + 1 : บรรทัดที่ ii ให้รับค่า wiw_i แทนราคาของอุปกรณ์ตามด้วยเลขอีก KK ตัว แทนว่าอุปกรณ์ชิ้นนั้นๆสามารถทำงานไหนได้บ้าง โดยจะมีค่าเป็น 1 ถ้าสามารถทำงานชนิดนั้นๆได้

ข้อมูลส่งออก

จำนวนเงินที่น้อยที่สุดที่สามารถซื้อของที่ทำงานได้ครบทุกอย่าง

ตัวอย่าง

Input Output
5 3
10 1 0 1
30 0 1 1
5 1 0 0
4 0 0 1
150 1 1 1
35

จากตัวอย่างมีอุปกรณ์อยู่ทั้งหมด 5 ชนิด และมีงาน 3 ประเภท เพื่อความง่ายเราจะเรียกว่าเป็นงานประเภท A, B และ C
โดยที่:

ชนิดที่ 1: ราคา 10 ใช้ทำงานประเภท A และ C ได้
ชนิดที่ 2: ราคา 30 ใช้ทำงานประเภท B และ C ได้
ชนิดที่ 3: ราคา 5 ใช้ทำงานประเภท A ได้
ชนิดที่ 4: ราคา 4 ใช้ทำงานประเภท C ได้
ชนิดที่ 5: ราคา 150 ใช้ทำงานได้ทุกประเภทเลย

คำอธิบาย: เราสามารถซื้ออุปกรณ์ชนิดที่ 2 และ 3 เพื่อให้ทำงานได้ครบ โดยจ่ายในราคาแค่ 35 ได้ โดยที่ไม่จำเป็นต้องซื้อชนิดที่ 5 ที่ทำได้ทุกอย่างในราคา 150


คำใบ้

จำนวนประเภทของงานมันมีน้อยมากๆ (แค่ 8 เอง) เมื่อเทียบกับค่าอื่นๆที่โจทย์กำหนดให้มา

เอาไปใช้ทำอะไรได้ไหมนะ??

วิเคราะห์โจทย์

ด้วยความว่ามันมีประเภทงานมันมีแค่ 8 แบบ แปลว่ามันมีแค่ 64 รูปแบบของการทำงานเท่านั้น (มาจาก 282^8 ) ซึ่งเราสามารถเก็บข้อมูลส่วนนี้ได้โดยการใช้แต่ละบิตมาแทนว่า งานไหนทำได้แล้วบ้าง

ยกตัวอย่างว่าถ้า เราสามารถทำงานประเภทที่ 3, 6 และ 7 ได้แล้ว ก็สามารถมาสร้างเป็น Bitmask ได้ดังนี้
โดยให้ 1 แทนว่าสามารถทำงานประเภทไหนได้แล้วบ้าง

0
0
1
0
0
1
1
0

บิตตำแหน่งที่ 3, 6 และ 7 มีค่าเป็น 1 แทนว่าทำงานประเภท 3, 6 และ 7 ได้แล้ว

การที่แปลงรูปแบบการทำงานเป็นแบบนี้ได้ประโยชน์อยู่ 2 อย่าง

  1. เรารู้แล้วว่ารูปแบบเริ่มต้นคือ 00000000 และรูปแบบที่เราต้องการคือ 11111111
  2. ในการซื้อของเพิ่ม เราสามารถคำนวณได้ในทันทีว่าทำงานประเภทไหนได้บ้างแล้ว

ยกตัวอย่าง เช่นถ้าเครื่องมือสามารถทำงานประเภท 1, 3 และ 6 ได้ เราก็สามารถแทนด้วยบิตได้ดังนี้

1
0
1
0
0
1
0
0

บิตที่ 1, 3 และ 6 มีค่าเป็น 1 แทนว่าทำงานประเภท 1, 3 และ 6 ได้

สมมติว่าถ้าเราสามารถทำงานประเภท 1, 2, 5 และ 6 ได้อยู่แล้ว ซึ่งสามารถแทนได้ด้วย

1
1
0
0
1
1
0
0

แทนประเภทงานที่เราทำได้

ถ้าเราซื้อของที่ว่ามานี่ แปลว่าเราต้องทำงาน 1, 2, 3, 5 และ 6 ได้แล้ว เพราะมีเครื่องมือสำหรับการทำงานประเภทที่ 3 แล้ว ที่แปลงเป็นบิตได้ว่า

1
1
1
0
1
1
0
0

งานที่ทำได้หลังซื้อ

1
0
1
0
0
1
0
0

อุปกรณ์ใหม่

1
1
0
0
1
1
0
0

งานที่ทำได้ก่อนหน้านี้

สังเกตว่าถ้าเอามาเทียบกันก็จะเห็นว่า การซื้อของมาเพิ่มก็คือการเอาบิตของสิ่งที่ซื้อมา มาทำ bitwise-or กับที่สิ่งที่เราเคยทำได้แล้วนั่นเอง และการที่เราต้องการทำให้ได้ทุกแบบก็คือการหา combination ที่ทำให้บิตกลายเป็น 1 ทั้งหมด

ทีนี้ปัญหาก็เหลือแค่ว่าจะหาราคาที่น้อยที่สุดในการซื้อยังไง ซึ่งแก้ไม่ยากถ้าเราสามารถกำหนด Dynamic State ให้โจทย์ได้

ข้อนี้มีอุปกรณ์อยู่ NN ชิ้นและมี state อยู่ทั้งหมด 23=82^3 = 8 แบบ เราสามารถกำหนดให้ dp[i][j]dp[i][j] แทน ค่าใช้จ่ายน้อยที่สุดที่เราสามารถทำ state j ได้โดยจากใช้อุปกรณ์ชิ้นที่ i เท่านั้น

0
5
4
9
30
35

ตัวอย่างตาราง dp ในแถวที่ N เมื่อคำนวณทุกอุปกรณ์แล้ว

จากข้อสังเกตก่อนหน้านี้ที่เรารู้ว่าการซื้อของมันเปลี่ยน state ยังไง
สมมติว่าถ้าเรารู้ว่าค่าใช้จ่ายน้อยสุดในการซื้อของเพื่อให้ได้ state xx โดยซื้อจากอุปกรณ์แค่ 1...(i1)1...(i-1)
หรือ ( d[i1,x]d[i-1,x] )

เราจะสามารถคำนวณหาว่า d[i,y]d[i,y] มีค่าเป็นเท่าไหร่ได้จาก

d[i,y]=d[i1,x]+wid[i, y] = d[i-1, x] + w_i

เมื่อ

  • xx แทน state ก่อนซื้อของ
  • yy แทน state หลังซื้อของชิ้นที่ i
  • wiw_i แทนราคาของชิ้นที่ i

ซึ่งเราสามารถค่อยๆเอาสมการนี้ไปคำนวณ เพื่อหา Dynamic State ที่ต้องการได้

ลิงก์เพิ่มเติม

โจทย์เต็มข้อ Equipped โพสต์ Original ใน Facebook
0

บทความอื่นๆ