news 2026/4/15 18:59:20

day166—递归—多边形三角剖分的最低得分(LeetCode-1039)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
day166—递归—多边形三角剖分的最低得分(LeetCode-1039)

题目描述

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

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

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

示例 1:

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

示例 2:

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

示例 3:

输入: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

解决方案:

这段代码是基于记忆化递归求解 “多边形三角剖分的最低得分” 问题的完整正确实现,核心思路是通过递归拆分多边形为子问题,结合记忆化缓存避免重复计算,最终得到整个多边形三角剖分的最小得分。

核心逻辑

  1. 核心定义

    • memo:二维记忆化数组(len×len),memo[begin][end]缓存顶点区间[begin, end]构成的子多边形三角剖分的最低得分,初始值为0xFFFFFF(标记 “未计算”);
    • dfs(begin, end, s):返回顶点区间[begin, end]三角剖分的最低得分,s为顶点值数组(传引用避免拷贝)。
  2. 递归边界

    • begin+1==end(仅 2 个顶点,无法构成三角形):返回 0(无剖分得分,是问题的基础边界);
    • 主函数补充len<3返回 0(边界防护:顶点数不足 3 时无法剖分,直接返回 0)。
  3. 记忆化优化:递归开始时先检查memo[begin][end]!=0xFFFFFF,若命中缓存(已计算过该区间的最小得分),则直接返回缓存值,避免重复递归计算,将时间复杂度从纯递归的O(2n)降至O(n3)(n为顶点数)。

  4. 核心状态转移(问题本质):枚举分割点ibegin < i < end),将[begin, end]多边形拆分为三个部分:

    • 左子多边形[begin, i]的剖分得分:dfs(begin, i, s)
    • 右子多边形[i, end]的剖分得分:dfs(i, end, s)
    • 当前三角形begin-i-end的得分:s[begin] * s[i] * s[end];总得分是三者之和,通过min取所有分割点对应的最小得分,即为[begin, end]区间的最低剖分得分。
  5. 主函数逻辑:初始化记忆化数组(填充0xFFFFFF标记未计算),调用dfs(0, len-1, values)计算整个多边形(顶点0~len-1)的最低剖分得分并返回。

关键特点

  • 逻辑完整:覆盖了边界条件、记忆化缓存、核心得分计算的所有关键环节,是该问题的标准记忆化递归解法;
  • 效率可控:记忆化缓存彻底避免重复递归,能处理中等规模的顶点数输入;
  • 实现简洁:基于递归框架,贴合 “将大问题拆分为子问题” 的动态规划思想,易理解、易维护。

总结

  1. 核心思路:通过递归枚举所有分割点,将大多边形拆分为子多边形 + 三角形,取所有剖分方式的得分最小值,结合记忆化缓存优化效率;
  2. 关键设计:memo数组是效率核心,分割点枚举 + 子问题递归 + 得分求和取最小是逻辑核心;
  3. 功能效果:能正确计算任意合法顶点数组的多边形三角剖分最低得分,结果无偏差。

values = [3,7,4,5]为例,代码会枚举分割点i=1i=2,计算所有剖分方式的得分后取最小值 144,返回正确结果。

函数源码:

class Solution { public: vector<vector<int>> memo={}; int dfs(int begin,int end,vector<int>& s){ int min_x=0xFFFFFF; if(begin+1==end) return 0; if(memo[begin][end]!=0xFFFFFF) return memo[begin][end]; for(int i=begin+1;i<end;i++){ min_x=min(min_x,dfs(begin,i,s)+dfs(i,end,s)+s[begin]*s[i]*s[end]); } memo[begin][end]=min_x; return min_x; } int minScoreTriangulation(vector<int>& values) { int len=values.size(); if(len<3)return 0; memo.assign(len,vector<int>(len,0xFFFFFF)); return dfs(0,len-1,values); } };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/10 14:46:27

(新卷,200分)- 区间交叠问题(Java JS Python)

(新卷,200分)- 区间交叠问题&#xff08;Java & JS & Python&#xff09;题目描述给定坐标轴上的一组线段&#xff0c;线段的起点和终点均为整数并且长度不小于1&#xff0c;请你从中找到最少数量的线段&#xff0c;这些线段可以覆盖柱所有线段。输入描述第一行输入为所…

作者头像 李华
网站建设 2026/4/14 1:59:28

(新卷,100分)- 事件推送(Java JS Python C)

(新卷,100分)- 事件推送&#xff08;Java & JS & Python & C&#xff09;题目描述同一个数轴X上有两个点的集合A{A1, A2, …, Am}和B{B1, B2, …, Bn}&#xff0c;Ai和Bj均为正整数&#xff0c;A、B已经按照从小到大排好序&#xff0c;A、B均不为空&#xff0c;给定…

作者头像 李华
网站建设 2026/4/7 8:01:29

Flutter for HarmonyOS 开发指南(二):Hello World

一&#xff1a;零基础快速入门Dart Flutter开发 这段代码是 Flutter 官方提供的标准“计数器”示例&#xff0c;也是学习 Flutter 的“Hello World”。现对它进行了一些修改&#xff08;添加了全局主题配置&#xff09;。 效果&#xff1a; 二&#xff1a;示例代码 main.dar…

作者头像 李华
网站建设 2026/4/1 23:51:04

sparse4D V2核心要点

这个图是sparseV2的结构&#xff0c;单帧网络输出的instance和历史帧的instance是如何在多帧网络里融合的&#xff1f;因为单帧网络基于当前img检出的结果肯定跟历史帧是有重叠的&#xff0c;初读文章的疑问是&#xff1a;如何把重合的这部分一一对应上呢一句话先给结论&#x…

作者头像 李华