"""
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