สมมติว่าเรามีอาร์เรย์ arr ของจำนวนเต็มบวก พิจารณาไบนารีทรีทั้งหมดเช่นนั้น −
- แต่ละโหนดมี 0 หรือ 2 ลูก
- ค่าของอาร์เรย์ arr สอดคล้องกับค่าของแต่ละลีฟในการข้ามผ่านของต้นไม้
- ค่าของโหนดที่ไม่ใช่ใบไม้แต่ละโหนดจะเท่ากับผลคูณของค่าลีฟที่ใหญ่ที่สุดในทรีย่อยด้านซ้ายและด้านขวาตามลำดับ
ในบรรดาต้นไม้ไบนารีที่เป็นไปได้ทั้งหมดที่เราพิจารณา เราต้องหาผลรวมที่น้อยที่สุดของค่าของแต่ละโหนดที่ไม่ใช่ใบไม้ ดังนั้นหากอินพุต arr เป็น [6,2,4] เอาต์พุตจะเป็น 32 เนื่องจากอาจมีต้นไม้สองต้น -
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
- สร้างแผนที่ชื่อบันทึก
- กำหนดวิธีการ dp() ซึ่งจะใช้ i และ j เป็นพารามิเตอร์ สิ่งนี้จะทำงานดังนี้ −
- ถ้า j <=i ให้คืนค่า 0
- ถ้า (i, j) ในบันทึกช่วยจำ ให้ส่งคืนบันทึก[(i, j)]
- res :=อินฟินิตี้
- สำหรับ k ในช่วง i ถึง j – 1
- res :=นาทีของ res, dp(i, k) + dp(k + 1, j) + (สูงสุดของ subarray ของ arr จากดัชนี i ถึง k + 1) * สูงสุดของ subarray ของ arr จาก k + 1 ถึง j + 1
- บันทึก[(i, j)] :=res
- return memo[(i, j)]
- เมธอดหลักจะเรียกเมธอด dp() นี้ว่า − โทร dp(0, ความยาวของ arr - 1)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
class Solution(object): def mctFromLeafValues(self, arr): """ :type arr: List[int] :rtype: int """ self. memo = {} def dp(i,j): if j<=i: return 0 if (i,j) in self.memo: return self.memo[(i,j)] res = float('inf') for k in range(i,j): res = min(res,dp(i,k) + dp(k+1,j) + (max(arr[i:k+1])*max(arr[k+1:j+1]))) self.memo[(i,j)]=res return self.memo[(i,j)] return dp(0,len(arr)-1)
อินพุต
[6,2,4]
ผลลัพธ์
32