diff --git a/md/cnc_2207_coconaht.md b/md/cnc_2207_coconaht.md new file mode 100644 index 0000000..413c831 --- /dev/null +++ b/md/cnc_2207_coconaht.md @@ -0,0 +1,40 @@ +# ปัญหาย่อยที่ 1 +ให้ $N \le 10$ เราสามารถคำนวนเส้นทางที่ยาวที่สุดโดยการทดลองทุก ๆ เส้นทางการเก็บมะพร้าว เส้นทางการเก็บมะพร้าวคือ permutation ของจำนวนมะพร้าวทั้งหมด ซึ่งมีทั้งสิ้น $\mathcal O ((R-L)!)$ เส้นทางระหว่างมะพร้าวลูกที่ $L$ ถึง $R$ ดังนั้น เราสามารถเลือกทุก ๆ $L$ และ $R$ แล้วลองทุกเส้นทางได้ โดยใช้เวลาทำงาน $\mathcal O(N^2N!)$ + +# ปัญหาย่อยที่ 1.5 (ไม่มีคะแนน) +ให้ $N \le 700$ เราจะพิจารณาหาเส้นทางการเก็บมะพร้าวที่ไกลที่สุดให้เร็วขึ้น โดยจะไม่ลองทุกเส้นทาง สังเกตว่าหากมีมะพร้าว $K$ ลูก เราจะมีช่วงระยะห่างระหว่างมะพร้าว $K-1$ ช่วง + +ระยะห่างช่วงแรกจะไม่สามารถถูกเดินมากกว่า 2 ครั้ง เพราะการเดินในช่วงนี้ 2 ครั้ง (ไปกลับ) จะต้องใช้มะพร้าวฝั่งซ้ายของช่วง 1 ลูก ตามรูป + +![](../media/cnc_2207_coconaht/first_interval.png) + +ในทำนองเดียวกัน ช่วงที่สองก็จะถูกเดินได้ไม่เกิน 4 ครั้ง ช่วงที่ 3 ได้ไม่เกิน 6 ครั้ง เป็นต้น + +หากพิจารณาจากอีกฝั่งหนึ่ง เริ่มจากริมขวาสุด ช่วงสุดท้าย (ช่วงที่ $N-1$) จะถูกเดินไม่เกิน 2 ครั้ง ช่วงที่ $N-2$ จะถูกเดินไม่เกิน 4 ครั้ง เป็นต้น +ดังนั้นค่ามากที่สุดที่เป็นไปได้คือ + +![](../media/cnc_2207_coconaht/theoretic_max.png) + +ซึ่งหากมีจำนวนช่วงเป็นจำนวนคี่ เราจะสามารถสร้างวิธีการเก็บโดยการเริ่มจากมะพร้าวลูกที่ $m+1, 1, m+2, 2, ..., n, m$ เมื่อ $m = \frac n2$ ซึ่งจะเก็บช่วงต่างครบตามค่ามากที่สุดของแต่ละช่วง ยกเว้นช่วงตรงกลางที่เก็บได้แค่ $2k-1$ เมื่อ $2k$ คือค่ามากสุดที่คิดไว้ด้านบน + +แต่หากมีจำนวนช่วงเป็นจำนวนคู่ เราจะสามารถสร้างวิธีการเก็บคล้าย ๆ กับด้านบน ซึ่งจะเก็บช่วงต่างครบตามค่ามากที่สุดของแต่ละช่วง ยกเว้นช่วงตรงกลางที่เก็บได้แค่ $2k-1$ เมื่อ $2k$ คือค่ามากสุดที่คิดไว้ด้านบนเช่นกัน แต่ในกรณีนี้ ช่วงตรงกลางมี 2 ช่วง เราสามารถเลือกช่วงใดก็ได้ที่จะเดินผ่าน $2k-1$ ครั้ง และเดินผ่านอีกช่วงนึง $2k$ ครั้ง + +เราสามารถพิสูจน์ให้ละเอียดขึ้นได้ว่า ไม่มีวิธีการเดินที่จะเก็บช่วงตรงกลางให้ครบ $2k$ ครั้ง ทำให้วิธีการเดินที่ระบุข้างบนเป็นวิธีที่ดีที่สุด + +เมื่อได้วิธีการเดินเก็บแล้ว เราสามารถวนทุกช่วง $[L, R]$ ของมะพร้าว และวน $\mathcal O(R-L)$ เพื่อคำนวนหาระยะทางโดยใช้สูตรข้างบน นั่นคือ 2 เท่าของช่วงแรก บวก 4 เท่าของช่วง 2 เรื่อย ๆ จนถึง 4 เท่าของช่วงรองสุดท้ายและ 2 เท่าของช่วงสุดท้าย + +จะใช้เวลาทำงานทั้งหมด $\mathcal O(N^3)$ + +# ปัญหาย่อยที่ 2 + +เราสามารถทำได้สองวิธีหลัก ๆ อย่างแรกคือการคิดระยะทางมากสุดของช่วง $[L, R]$ ให้ได้ใน $\mathcal O(1)$ และอย่างที่สองคือการลดจากการวนทุกช่วง $[L, R]$ ให้เหลือแค่ $\mathcal O(N\log N)$ ช่วง + +การทำ**ทั้งสองอย่าง**นี้จะทำให้แก้ปัญหาย่อย 3-4 ได้ด้วย + +# ปัญหาย่อยที่ 3-4 + +เราสามารถใช้ quick sum ช่วยในการคำนวนระยะทางมากสุดของช่วง $[L, R]$ ให้ได้ใน $\mathcal O(1)$ + +สังเกตว่าเราไม่จำเป็นต้องคำนวนทุกช่วง $[L, R]$ เนื่องจากหากช่วง $[L, R]$ ใดระยะทางรวมเกิน $K$ ช่วงที่ใหญ่กว่านั้นก็จะมีระยะทางเกิน $K$ ด้วย เราสามารถใช้การ binary search ช่วงของ $R$ ในทุก ๆ $L$ เพื่อจะคิดแค่ $\mathcal O(N \log N)$ ช่วงหรือใช้ 2 pointers เพื่อจะคิดแค่ $\mathcal O(N)$ ช่วงก็ได้ + +เวลาในการทำงาน $\mathcal O(N)$ \ No newline at end of file diff --git a/media/cnc_2207_coconaht/first_interval.png b/media/cnc_2207_coconaht/first_interval.png new file mode 100644 index 0000000..c08a87c Binary files /dev/null and b/media/cnc_2207_coconaht/first_interval.png differ diff --git a/media/cnc_2207_coconaht/theoretic_max.png b/media/cnc_2207_coconaht/theoretic_max.png new file mode 100644 index 0000000..ba2783e Binary files /dev/null and b/media/cnc_2207_coconaht/theoretic_max.png differ