กำหนดให้ Hi,j เป็นความสูงของช่อง (i,j)
ในข้อนี้ เราจะสามารถหาคำตอบได้ด้วยการใช้ Dynamic Programming โดยกำหนดให้ dp(i,j) เป็นพลังงานที่น้อยที่สุดที่ใช้ในการกระโดดจาก (1,1) มายัง (i,j)
ในการกระโดดมายังช่อง (i,j) เราสามารถแบ่งออกเป็น 2 กรณีดังที่โจทย์กำหนดมาคือ
- กระโดดในแนวแถวจากช่อง (i,k) เมื่อ k<j
- กระโดดในแนวคอลลัมน์จากช่อง (k,j) เมื่อ k<i
การหาค่า dp(i,j) สามารถทำได้โดยกำหนดให้ dp(1,1):=0 เป็น Base Case และสำหรับ dp(i,j) ใด ๆ จะได้ว่าดังนี้
สำหรับกรณีที่ 1 เราจะได้ว่า dp(i,j)=1≤k<j,Hi,k<Hi,jmin{dp(i,k)+l=k+1∑j−1Hi,l}
สำหรับกรณีที่ 2 เราจะได้ว่า dp(i,j)=1≤k<i,Hk,j<Hi,jmin{dp(k,j)+l=k+1∑i−1Hl,i}
เราจะเลือกกรณีที่ทำให้ dp(i,j) มีค่าน้อยที่สุด แล้วคำตอบสุดท้ายของโจทย์จะเป็น dp(R,C)
หากเราทำตาม Recurrence Formula ด้านบนนี้ตรง ๆ จะไม่ทันเวลาที่โจทย์ได้กำหนดไว้ ดังนั้นเราจึงต้องทำ Optimization โดยวิธีดังต่อไปนี้จะอธิบายเฉพาะกรณีที่ 1 เท่านั้นเนื่องจากทั้งสองกรณีใช้วิธีที่คล้ายคลึงกัน
การหาผลรวม l=k+1∑j−1Hi,l เราสามารถลดเวลาการทำงานได้โดย กำหนดให้ prefi,j=k=1∑jHi,k หรือ Prefix Sum ของแต่ละแถวนั่นเอง ผลรวมดังกล่าวจะมีค่าเท่ากับ prefi,j−1−prefi,k ซึ่งลดเวลาการทำงานเป็น O(1) เท่านั้น แต่ก็นังไม่เพียงพอที่จะทำให้ทำงานทันภายในเวลา
พิจารณาเฉพาะแถว i สังเกตว่าค่า prefi,j−1 จะถูกรวมในพลังงานที่ใช้เสมอ ดังนั้นจะได้ว่า dp(i,j)=1≤k<j,Hi,k<Hi,jmin{dp(i,k)−prefi,k}+prefi,j−1 เราจึงจำเป็นต้องสนใจเพียงค่าของ dp(i,k)−prefi,k เท่านั้น
และจากเงื่อนไขของโจทย์ที่ว่า Hi,k<Hi,j เราจึงต้องทำ Coordinate Compression บนค่า Hi,j เมื่อ 1≤j≤C เก็บในอาร์เรย์ coord เมื่อสมาชิกเรียงจากน้อยไปมาก แล้วใช้ Segment Tree ที่รองรับการหาค่าที่น้อยที่สุดในช่วง เก็บค่า dp(i,j) ทำให้เราสามารถหาค่า dp(i,j) ภายใน O(logC) ได้
นอกจากนี้ เราจะพิจารณาค่า dp(i,j) จาก j=1,2,…,C และสำหรับ dp(i,j) ที่ยังไม่ได้หาค่า จะกำหนดให้เป็น ∞ ก่อน เพื่อให้ตรงตามเงื่อนไขที่ว่า k<j เสมอ
วิธีดังกล่าวนี้ สามารถนำไปปรับใช้ในการกระโดดกรณีที่ 2 ได้ ทำให้ใช้ Segment Tree ทั้งหมด R+C ต้น และทำการ Coordinate Compression ทั้งหมด R+C ครั้ง
Time Complexity: O(RClogRC)