"""
2023.04.02 | 1039. 多邊形三角剖分的最低得分
https://leetcode.cn/problems/minimum-score-triangulation-of-polygon/
題目分析:
這題中等難度,可以用dfs和dp求解。
具體圖解詳見excel附件
理論1:dfs
將頂點分割的區域分成:
left,current和right;left和right需要繼續遞歸計算;
currrent按題目要求求解,最後返回條件的最小值
理論2:dp
從大到小枚舉i,從小到大枚舉j,計算dp[i][j]
k=循環i,j之間的頂點
注意/難點:
需要初始化面積area=sys.maxsize
"""
import sys
from functools import lru_cache
import numpy as np
class Solution:
def minScoreTriangulation_dfs(self, values) -> int:
#dfs主程序,left,right分別表示左,右頂點
@lru_cache(None) #緩存裝飾器,記憶化DFS結果
def dfs(left,right):
if right<left+2: #只有兩個頂點,返回0
return 0
else:
area=sys.maxsize
#枚舉從left後面開始到right的所有頂點,進行分成三角形
for k in range(left+1,right):
print(left,k,right) #debug
area=min(area,dfs(left,k)+values[left]*values[k]*values[right]+dfs(k,right))
return area
n=len(values) #頂點個數
return dfs(0,n-1) #開始遞歸
def minScoreTriangulation_dp(self, values) -> int:
n=len(values) #數組長度
dp=[[0]*n for _ in range(n)] #初始化dp
for i in range(n-1,-1,-1): #從大到小枚舉i
#+2確保至少有3個點
for j in range(i+2,n): #從小到大枚舉j
dp[i][j]=sys.maxsize #初始化極大值
for k in range(i+1,j): #循環i,j之間的頂點
#計算最小值
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+values[i]*values[k]*values[j])
print(np.array(dp))
return dp[0][n-1] #返回值
values = [3,7,4,5]
# ans=Solution().minScoreTriangulation_dfs(values)
ans=Solution().minScoreTriangulation_dp(values)
print(ans)
輸出的dp變化如下:
具體dfs和dp的解題思路:
dfs:
dp