โจทย์ข้อนี้กำหนดให้มีหออยู่ N หอ โดยแต่ละหอมีพิกัด xi กับ yi และมีนักเรียน si คน โจทย์ต้องการให้หาว่าหากเลือกพิกัด x y ให้ดีที่สุดจะทำให้ Σisi(∣xi−x∣+∣yi−y∣) ได้ต่ำสุดเท่าไหร่
สำหรับข้อนี้สามารถสังเกตว่า Σisi∗(∣xi−x∣+∣yi−y∣)=Σisi∣xi−x∣+Σisi∣yi−y∣ จึงสามารถพิจารณาระยะทางในพิกัด x กับพิกัด y แยกกันในการหาคำตอบ
ค่ามัธยฐาน
คุณสมบัติที่สำคัญที่ต้องใช้การแก้ข้อนี้คือ Σi=1N∣ai−a∣ จะมีค่าต่ำสุดเมื่อเลือก a เป็นค่ามัธยฐานของ (a1,a2,…,aN) โดยนิยามค่ามัธยฐาน m เป็นค่าที่ทำให้มีจำนวน ai ที่ไม่น้อยกว่า m อย่างน้อยครึ่ง และจำนวน ai ที่มีค่าไม่เกิน m อย่างน้อยครึ่ง (ตามนิยามนี้อาจมีค่ามัธยฐานมากกว่า 1 ค่า เช่น สำหรับ 1,2,3,4,5,6 ทั้ง 3,4 และ 3.5 ต่างเป็นค่ามัธยฐาน)
เนื่องจากข้อนี้ยังมีค่า si ที่ต้องพิจารณาด้วยเราจะพิสูจน์ว่าพิกัด x ที่ต้องการคือค่า m ที่ทำให้ Σi,m≤xisi≥2Σisi และ Σi,m≥xisi≥2Σisi กล่าวคือนักเรียนที่อยู่ที่พิกัด x ที่ไม่น้อยกว่า m มีอย่างน้อยครึ่ง และไม่มากกว่า m อย่างน้อยครึ่ง
สำหรับการหา Σisi∣xi−m∣ สังเกตว่า Σisi∣xi−m∣=Σi,m≥xisi(m−xi)+Σi,m<xisi(xi−m) สมมติว่า Σi,m≥xisi<Σi,m<xisi จะได้ว่าถ้าเพิ่มค่า m เป็น m+ϵ โดยที่ 0<ϵ<minxi<m(m−xi) จะทำให้ผลรวมนี้ลดลง เนื่องจาก Σi,m≥xisi(m+ϵ−xi)+Σi,m<xisi(xi−m−ϵ)=Σisi∣xi−m∣+ϵ(Σi,m≥xisi−Σi,m<xisi)<Σisi∣xi−m∣ (เลือก ϵ<minxi<m(m−xi) เพราะจะทำให้ทุก xi ยังอยู่ในทางซ้ายหรือขวาของ m อยู่ฝั่งเดิมเมื่อเปลี่ยนเป็น m+ϵ)
ดังนั้นสำหรับ m ที่ทำให้ผลรวมที่ต้องการมีค่าต่ำสุดจะต้องได้ว่า Σi,m≥xisi≥Σi,m<xisi⟹Σi,m≥xisi+Σi,m≥xisi≥Σi,m<xisi+Σi,m≥xisi=Σisi⟹Σi,m≥xisi≥2Σisi ตามที่ต้องการ เราสามารถพิสูจน์ด้วยวิธีเดียวกันว่าจะต้องได้ว่า Σi,m≤xisi≥2Σisi เช่นกัน
โดยสรุปคือเราต้องการเลือกพิกัด x=m ที่ทำให้ และ Σi,m≥xisi≥2Σisi และ Σi,m≤xisi≥2Σisi กล่าวคือต้องการเลือกค่ามัธยฐานของพิกัด x ของนักเรียนทุกคนนั่นเองซึ่งพิกัด x ที่เป็นอันดับที่ ⌊2Σisi⌋ จะเข้าทั้งสองเงื่อนไขไม่ว่า Σisi จะเป็นจำนวนคู่หรือจำนวนคี่
การเลือกค่ามัธยฐานโดยตรงด้วยการ sort ทั้ง x และ y และนับผลรวม si จะช้าเกินไปสำหรับ N=500000 เนื่องจากข้อนี้ให้เวลาเพียง 0.5 วินาที และการ sort ใช้เวลา O(NlogN)
Quickselect
ขั้นตอนวิธีมาตรฐานในการเลือกค่าอันดับที่ k คือ Quickselect ซึ่งมี Expected Time Complexity O(N)
Quickselect จะรับค่าเป็น Array A[b..e] และค่า k ซึ่งแทนอันดับที่ต้องการ และ return ค่าที่เป็นอันดับ k ใน A[b..e]
Quickselect มีลักษณะคล้าย Quicksort คือในแต่ละขั้น Quickselect จะสุ่มเลือก pivot มาเพื่อแยกข้อมูลที่ยังพิจารณาเป็น 2 กลุ่ม คือกลุ่มที่มาก่อนและมาหลัง pivot จากนั้นจะเรียก Quickselect อีกรอบแบบ recursive ในกลุ่มที่มีค่าอันดับที่ต้องการ สำหรับข้อนี้จะต้องดัดแปลงให้สามารถพิจารณาจำนวนนักเรียน si ในแต่ละหอด้วย
ขั้นตอนวิธี Quickselect สามารถเขียนเป็น
- หากข้อมูลที่พิจารณามีเพียง 1 หอ ให้ return ค่า x ของหอนี้
- สุ่มเลือกหอหนึ่งมาเป็น pivot และแยกข้อมูลเป็น 2 ส่วน คือหอที่มีค่า x<xpivot และหอที่มีค่า x>xpivot (สำหรับหอที่มีค่า x เท่ากันให้สุ่มว่าจะไว้กลุ่มแรกหรือหลังแบบสุ่มครึ่งครึ่ง) ให้ p เป็นจำนวนหอในกลุ่มแรกบวก 1 สามารถเอา pivot ไปไว้ที่ตำแหน่ง A[p] และสลับกลุ่มแรกมาไว้ใน A[b..(p−1)] และกลุ่มหลังไว้ใน A[(p+1)..e] จะทำให้ทุกหอใน A[b..(p−1)] มีพิกัด x ไม่เกิน xpivot และใน A[(p+1)..e] ไม่ต่ำกว่า xpivot
- ให้ผลรวม si ในกลุ่มหน้าเป็น Sfront และในกลุ่มหลังเป็น Sback ถ้า Sfront≥k ให้ Quickselect ค่าที่ k ใน A[b..(p−1)] และ return ค่าที่ได้ ถ้า Sback>k ให้ Quickselect ค่าที่ k−spivot−Sback ใน A[(p+1)..e] หากไม่เข้าทั้งสองกรณีให้ return ค่า xpivot เพราะจะเป็นค่าที่เป็นอันดับ k แล้ว
สังเกตว่าขั้นตอนวิธีนี้มี Worst Case Time Complexity O(N2) เช่นเดียวกับ Quicksort เช่นหากเลือกหอที่มี x ต่ำสุดในทุกรอบ อย่างไรก็ตามเราสามารถพิสูจน์ว่า Expected Time Complexity ของขั้นตอนวิธีนี้เป็นเพียง O(N)
ให้เวลาที่ขั้นตอนวิธีนี้ใช้สำหรับ N ค่าเป็น T(N) จะได้ recurrence ว่า E[T(N)]=N1Σi=1NE[T(i)]+O(N) โดย E[T(1)]=T(1)=1 ซึ่งจะพิสูจน์โดย induction ได้ว่า E[T(N)]=O(N) (เพราะจะได้ E[T(N)]=N1Σi=1NE[T(i)]+O(N)=N1Σi=1NO(i)+O(N)≤N1Σi=1NCi+O(N)=NC2N(N−1)+O(N)=C2N−1+O(N)=O(N) )
Solution
เมื่อรู้แล้วว่าค่า x และ y ที่จะทำให้ระยะทางต่ำสุดเป็นค่ามัธยฐานของพิกัดนักเรียนในแต่ละแกน เราสามารถใช้ Quickselect เลือกค่า x และ y ดังกล่าวและคำนวน Σisi∣xi−x∣+Σisi∣yi−y∣ โดยตรง โดยทั้งหมดใช้ Expected Time Complexity O(N)