Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions md/cnc_2207_coconaht.md
Original file line number Diff line number Diff line change
@@ -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)$
Binary file added media/cnc_2207_coconaht/first_interval.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/cnc_2207_coconaht/theoretic_max.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.