LeetCode探索(56):1039-多边形三角剖分的最低得分

275 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

题目

你有一个凸的 n 边形,其每个顶点都有一个整数值。给定一个整数数组 values ,其中 values[i] 是第 i 个顶点的值(即 顺时针顺序 )。

假设将多边形 剖分n - 2 个三角形。对于每个三角形,该三角形的值是顶点标记的乘积,三角剖分的分数是进行三角剖分后所有 n - 2 个三角形的值之和。

返回 多边形进行三角剖分后可以得到的最低分

示例 1:

img

输入:values = [1,2,3]
输出:6
解释:多边形已经三角化,唯一三角形的分数为 6。

示例 2:

img

输入:values = [3,7,4,5]
输出:144
解释:有两种三角剖分,可能得分分别为:3*7*5 + 4*5*7 = 245,或 3*4*5 + 3*4*7 = 144。最低分数为 144

示例 3:

img

输入:values = [1,3,1,4,1,5]
输出:13
解释:最低分数三角剖分的得分情况为 1*1*3 + 1*1*4 + 1*1*5 + 1*1*1 = 13

提示:

  • n == values.length
  • 3 <= n <= 50
  • 1 <= values[i] <= 100

思考

本题难度中等。不过,该题咋一看没什么思路,自我感觉还是很难的!

定义dp[i][j]为区间[i, j]的三角剖分最低得分, 因此题目所求即为dp[0][n - 1]

显然,当我们只取出1个顶点(i == j)或只取出两个顶点(i + 1 == j)时,无法组成三角形,此时 dp[i][j] === 0

递推过程是从左下到右上的,因此 i 取值 n - 3,j 取值 i + 2,而 m 在(i,j)范围内进行遍历。状态转移方程为:dp[i][j] = Math.min(dp[i][j], values[i] * values[j] * values[m] + dp[i][m] + dp[m][j])

解答

方法一:动态规划

/**
 * @param {number[]} values
 * @return {number}
 */
var minScoreTriangulation = function(values) {
  let n = values.length
  const dp = new Array(n).fill(0).map(() => new Array(n).fill(0))
  for (let i = n - 3; i >= 0; i--) {
      for (let j = i + 2; j < n; j++) {
        for (let m = i + 1; m < j; m++) {
          if(dp[i][j] === 0) {
            dp[i][j] = values[i] * values[j] * values[m] + dp[i][m] + dp[m][j]
          } else {
            dp[i][j] = Math.min(dp[i][j], values[i] * values[j] * values[m] + dp[i][m] + dp[m][j])
          }
        }
      }
  }
  return dp[0][n - 1]
}
// console.log(minScoreTriangulation([1,2,3])) // 6
// console.log(minScoreTriangulation([3,7,4,5])) // 144
​
// 执行用时:72 ms, 在所有 JavaScript 提交中击败了25.00%的用户
// 内存消耗:42.2 MB, 在所有 JavaScript 提交中击败了50.00%的用户
// 通过测试用例:94 / 94

复杂度分析

  • 时间复杂度:O(n^3),n为数组values的长度。
  • 空间复杂度:O(n^2),需要构建二维数组dp。

参考