多边形三角剖分的最低得分–LeetCode1039
题目
给定 N
,想象一个凸 N
边多边形,其顶点按顺时针顺序依次标记为 A[0],A[1],...,A[i],...,A[N-1]
。假设您将多边形剖分为 N-2
个三角形。对于每个三角形,该三角形的值是顶点标记的乘积,三角剖分的分数是进行三角剖分后所有 N-2
个三角形的值之和。返回多边形进行三角剖分后可以得到的最低分。
示例 1:
输入:[1,2,3]
输出:6
解释:多边形已经三角化,唯一三角形的分数为 6。
示例 2:
输入:[3,7,4,5]
输出:144
解释:有两种三角剖分,可能得分分别为:3*7*5 + 4*5*7 = 245,
或 3*4*5 + 3*4*7 = 144。最低分数为 144。
示例 3:
输入:[1,3,1,4,1,5]
输出:13
解释:最低分数三角剖分的得分情况为 1*1*3 + 1*1*4 + 1*1*5 + 1*1*1 = 13。
提示:
- 3 <= A.length <= 50
- 1 <= A[i] <= 100
思路
分析一个较大凸多边形进行三角剖分得到的最低分时,需要用到包含在该较大多边形中的小凸多边形的三角剖分的最低分。多边形三角剖分的示意图如下图所示。这是对区间[i, j]
进行三角剖分,选取了区间中的一个点k
,i-k
这条线分出了上面一个小多边形,k-j
这条线分出了下面一个小多边形,虚线表示区间[i, k]
和[k, j]
之间的顶点个数不确定,可能是一个也可能是多个。
dp数组含义:dp[i][j]
为区间[i, j]
的多边形三角剖分的最低得分。那么最终的结果肯定是整个区间的三角剖分的最低得分,即dp[0][n-1]
,其中n为数组长度。
转移方程:
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + A[i]* A[k] * A[j]), k∈(i,j)
(后面一部分就是根据上面的三角剖分示意图得出来的)
初始化:因为需要求得分的最小值,所以dp数组中每个元素要初始化为整型的最大值。其次两个点是无法构成三角形的,所以dp[i][i+1]=0
代码如下:
class Solution {
public int minScoreTriangulation(int[] A) {
if (A == null || A.length == 0) {
return 0;
}
int n = A.length;
int[][] dp = new int[n][n];
// 初始化每个元素为整型的最大值
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dp[i][j] = Integer.MAX_VALUE;
}
}
// 两个点是无法构成三角形的
for (int i = 0; i < n-1; i++) {
dp[i][i+1] = 0;
}
// 枚举区间长度:len表示i和j的间隔,要构成三角形,至少间隔两个点
for (int len = 2; len < n; len++) {
for (int i = 0; i < n; i++) {//枚举区间的起点
int j = i+len;//根据起点和长度得到终点
if (j >= n) continue;
for (int k = i+1; k < j; k++) {//枚举该区间的分割点
dp[i][j] = Math.min(dp[i][j], dp[i][k]+dp[k][j]+A[i]*A[k]*A[j]);
}
}
}
return dp[0][n-1];
}
}