Skip to content

Commit e25e85b

Browse files
committed
feat: add solutions to lc problem: No.1039
No.1039.Minimum Score Triangulation of Polygon
1 parent 304dc4d commit e25e85b

File tree

6 files changed

+606
-0
lines changed

6 files changed

+606
-0
lines changed

solution/1000-1099/1039.Minimum Score Triangulation of Polygon/README.md

+284
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,306 @@
6060

6161
<!-- 这里可写通用的实现逻辑 -->
6262

63+
**方法一:记忆化搜索**
64+
65+
我们设计一个函数 $dfs(i, j)$,表示将多边形的顶点 $i$ 到 $j$ 进行三角剖分后的最低分数。那么答案就是 $dfs(0, n - 1)$。
66+
67+
函数 $dfs(i, j)$ 的计算过程如下:
68+
69+
如果 $i + 1 = j$,说明多边形只有两个顶点,无法进行三角剖分,返回 $0$;
70+
71+
否则,我们枚举 $i$ 和 $j$ 之间的一个顶点 $k$,即 $i \lt k \lt j$,将多边形的顶点 $i$ 到 $j$ 进行三角剖分,可以分为两个子问题:将多边形的顶点 $i$ 到 $k$ 进行三角剖分,以及将多边形的顶点 $k$ 到 $j$ 进行三角剖分。这两个子问题的最低分数分别为 $dfs(i, k)$ 和 $dfs(k, j)$,而顶点 $i$, $j$ 和 $k$ 构成的三角形的分数为 $values[i] \times values[k] \times values[j]$。那么,此次三角剖分的最低分数为 $dfs(i, k) + dfs(k, j) + values[i] \times values[k] \times values[j]$,我们取所有可能的最小值,即为 $dfs(i, j)$ 的值。
72+
73+
为了避免重复计算,我们可以使用记忆化搜索,即使用哈希表或者数组来存储已经计算过的函数值。
74+
75+
最后,我们返回 $dfs(0, n - 1)$ 即可。
76+
77+
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为多边形的顶点数。
78+
79+
**方法二:动态规划**
80+
81+
我们可以将方法一中的记忆化搜索改为动态规划。
82+
83+
定义 $f[i][j]$ 表示将多边形的顶点 $i$ 到 $j$ 进行三角剖分后的最低分数。初始时 $f[i][j]=0$,答案为 $f[0][n-1]$。
84+
85+
对于 $f[i][j]$(这里要求 $i + 1 \lt j$),我们先将 $f[i][j]$ 初始化为 $\infty$。
86+
87+
我们枚举 $i$ 和 $j$ 之间的一个顶点 $k$,即 $i \lt k \lt j$,将多边形的顶点 $i$ 到 $j$ 进行三角剖分,可以分为两个子问题:将多边形的顶点 $i$ 到 $k$ 进行三角剖分,以及将多边形的顶点 $k$ 到 $j$ 进行三角剖分。这两个子问题的最低分数分别为 $f[i][k]$ 和 $f[k][j]$,而顶点 $i$, $j$ 和 $k$ 构成的三角形的分数为 $values[i] \times values[k] \times values[j]$。那么,此次三角剖分的最低分数为 $f[i][k] + f[k][j] + values[i] \times values[k] \times values[j]$,我们取所有可能的最小值,即为 $f[i][j]$ 的值。
88+
89+
综上,我们可以得到状态转移方程:
90+
91+
$$
92+
f[i][j]=
93+
\begin{cases}
94+
0, & i+1=j \\
95+
\min_{i<k<j} \{f[i][k]+f[k][j]+values[i] \times values[k] \times values[j]\}, & i+1<j
96+
\end{cases}
97+
$$
98+
99+
注意,在枚举 $i$ 和 $j$ 时,我们可以有两种枚举方式:
100+
101+
1. 从大到小枚举 $i$,从小到大枚举 $j$,这样可以保证在计算状态 $f[i][j]$ 时,状态 $f[i][k]$ 和 $f[k][j]$ 都已经计算过了;
102+
1. 从小到大枚举区间长度 $l$,其中 $3 \leq l \leq n$,然后枚举区间左端点 $i$,那么可以得到右端点 $j=i + l - 1$,这样也可以保证在计算较大区间 $f[i][j]$ 时,较小区间 $f[i][k]$ 和 $f[k][j]$ 都已经计算过了。
103+
104+
最后,我们返回 $f[0][n-1]$ 即可。
105+
106+
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为多边形的顶点数。
107+
63108
<!-- tabs:start -->
64109

65110
### **Python3**
66111

67112
<!-- 这里可写当前语言的特殊实现逻辑 -->
68113

69114
```python
115+
class Solution:
116+
def minScoreTriangulation(self, values: List[int]) -> int:
117+
@cache
118+
def dfs(i: int, j: int) -> int:
119+
if i + 1 == j:
120+
return 0
121+
return min(dfs(i, k) + dfs(k, j) + values[i] * values[k] * values[j] for k in range(i + 1, j))
122+
123+
return dfs(0, len(values) - 1)
124+
```
70125

126+
```python
127+
class Solution:
128+
def minScoreTriangulation(self, values: List[int]) -> int:
129+
n = len(values)
130+
f = [[0] * n for _ in range(n)]
131+
for i in range(n - 3, -1, -1):
132+
for j in range(i + 2, n):
133+
f[i][j] = min(f[i][k] + f[k][j] + values[i] * values[k] * values[j] for k in range(i + 1, j))
134+
return f[0][-1]
135+
```
136+
137+
```python
138+
class Solution:
139+
def minScoreTriangulation(self, values: List[int]) -> int:
140+
n = len(values)
141+
f = [[0] * n for _ in range(n)]
142+
for l in range(3, n + 1):
143+
for i in range(n - l + 1):
144+
j = i + l - 1
145+
f[i][j] = min(f[i][k] + f[k][j] + values[i] * values[k] * values[j] for k in range(i + 1, j))
146+
return f[0][-1]
71147
```
72148

73149
### **Java**
74150

75151
<!-- 这里可写当前语言的特殊实现逻辑 -->
76152

77153
```java
154+
class Solution {
155+
private int n;
156+
private int[] values;
157+
private Integer[][] f;
158+
159+
public int minScoreTriangulation(int[] values) {
160+
n = values.length;
161+
this.values = values;
162+
f = new Integer[n][n];
163+
return dfs(0, n - 1);
164+
}
165+
166+
private int dfs(int i, int j) {
167+
if (i + 1 == j) {
168+
return 0;
169+
}
170+
if (f[i][j] != null) {
171+
return f[i][j];
172+
}
173+
int ans = 1 << 30;
174+
for (int k = i + 1; k < j; ++k) {
175+
ans = Math.min(ans, dfs(i, k) + dfs(k, j) + values[i] * values[k] * values[j]);
176+
}
177+
return f[i][j] = ans;
178+
}
179+
}
180+
```
181+
182+
```java
183+
class Solution {
184+
public int minScoreTriangulation(int[] values) {
185+
int n = values.length;
186+
int[][] f = new int[n][n];
187+
for (int i = n - 3; i >= 0; --i) {
188+
for (int j = i + 2; j < n; ++j) {
189+
f[i][j] = 1 << 30;
190+
for (int k = i + 1; k < j; ++k) {
191+
f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + values[i] * values[k] * values[j]);
192+
}
193+
}
194+
}
195+
return f[0][n - 1];
196+
}
197+
}
198+
```
199+
200+
```java
201+
class Solution {
202+
public int minScoreTriangulation(int[] values) {
203+
int n = values.length;
204+
int[][] f = new int[n][n];
205+
for (int l = 3; l <= n; ++l) {
206+
for (int i = 0; i + l - 1 < n; ++i) {
207+
int j = i + l - 1;
208+
f[i][j] = 1 << 30;
209+
for (int k = i + 1; k < j; ++k) {
210+
f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + values[i] * values[k] * values[j]);
211+
}
212+
}
213+
}
214+
return f[0][n - 1];
215+
}
216+
}
217+
```
218+
219+
### **C++**
220+
221+
```cpp
222+
class Solution {
223+
public:
224+
int minScoreTriangulation(vector<int>& values) {
225+
int n = values.size();
226+
int f[n][n];
227+
memset(f, 0, sizeof(f));
228+
function<int(int, int)> dfs = [&](int i, int j) -> int {
229+
if (i + 1 == j) {
230+
return 0;
231+
}
232+
if (f[i][j]) {
233+
return f[i][j];
234+
}
235+
int ans = 1 << 30;
236+
for (int k = i + 1; k < j; ++k) {
237+
ans = min(ans, dfs(i, k) + dfs(k, j) + values[i] * values[k] * values[j]);
238+
}
239+
return f[i][j] = ans;
240+
};
241+
return dfs(0, n - 1);
242+
}
243+
};
244+
```
245+
246+
```cpp
247+
class Solution {
248+
public:
249+
int minScoreTriangulation(vector<int>& values) {
250+
int n = values.size();
251+
int f[n][n];
252+
memset(f, 0, sizeof(f));
253+
for (int i = n - 3; i >= 0; --i) {
254+
for (int j = i + 2; j < n; ++j) {
255+
f[i][j] = 1 << 30;
256+
for (int k = i + 1; k < j; ++k) {
257+
f[i][j] = min(f[i][j], f[i][k] + f[k][j] + values[i] * values[k] * values[j]);
258+
}
259+
}
260+
}
261+
return f[0][n - 1];
262+
}
263+
};
264+
```
265+
266+
```cpp
267+
class Solution {
268+
public:
269+
int minScoreTriangulation(vector<int>& values) {
270+
int n = values.size();
271+
int f[n][n];
272+
memset(f, 0, sizeof(f));
273+
for (int l = 3; l <= n; ++l) {
274+
for (int i = 0; i + l - 1 < n; ++i) {
275+
int j = i + l - 1;
276+
f[i][j] = 1 << 30;
277+
for (int k = i + 1; k < j; ++k) {
278+
f[i][j] = min(f[i][j], f[i][k] + f[k][j] + values[i] * values[k] * values[j]);
279+
}
280+
}
281+
}
282+
return f[0][n - 1];
283+
}
284+
};
285+
```
286+
287+
### **Go**
288+
289+
```go
290+
func minScoreTriangulation(values []int) int {
291+
n := len(values)
292+
f := [50][50]int{}
293+
var dfs func(int, int) int
294+
dfs = func(i, j int) int {
295+
if i+1 == j {
296+
return 0
297+
}
298+
if f[i][j] != 0 {
299+
return f[i][j]
300+
}
301+
f[i][j] = 1 << 30
302+
for k := i + 1; k < j; k++ {
303+
f[i][j] = min(f[i][j], dfs(i, k)+dfs(k, j)+values[i]*values[k]*values[j])
304+
}
305+
return f[i][j]
306+
}
307+
return dfs(0, n-1)
308+
}
309+
310+
func min(a, b int) int {
311+
if a < b {
312+
return a
313+
}
314+
return b
315+
}
316+
```
317+
318+
```go
319+
func minScoreTriangulation(values []int) int {
320+
n := len(values)
321+
f := [50][50]int{}
322+
for i := n - 3; i >= 0; i-- {
323+
for j := i + 2; j < n; j++ {
324+
f[i][j] = 1 << 30
325+
for k := i + 1; k < j; k++ {
326+
f[i][j] = min(f[i][j], f[i][k]+f[k][j]+values[i]*values[k]*values[j])
327+
}
328+
}
329+
}
330+
return f[0][n-1]
331+
}
332+
333+
func min(a, b int) int {
334+
if a < b {
335+
return a
336+
}
337+
return b
338+
}
339+
```
78340

341+
```go
342+
func minScoreTriangulation(values []int) int {
343+
n := len(values)
344+
f := [50][50]int{}
345+
for l := 3; l <= n; l++ {
346+
for i := 0; i+l-1 < n; i++ {
347+
j := i + l - 1
348+
f[i][j] = 1 << 30
349+
for k := i + 1; k < j; k++ {
350+
f[i][j] = min(f[i][j], f[i][k]+f[k][j]+values[i]*values[k]*values[j])
351+
}
352+
}
353+
}
354+
return f[0][n-1]
355+
}
356+
357+
func min(a, b int) int {
358+
if a < b {
359+
return a
360+
}
361+
return b
362+
}
79363
```
80364

81365
### **...**

0 commit comments

Comments
 (0)