【每日一题Day165】LC1039多边形三角剖分的最低得分 | 区间dp

文章介绍了如何解决一个关于多边形三角剖分的问题,目标是最小化由顶点值计算出来的三角形得分之和。提供了两种解决方案,一种是递归方法,另一种是动态规划方法,两者的时间复杂度均为O(n^3),空间复杂度为O(n^2)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多边形三角剖分的最低得分【LC1039】

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

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

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

感觉dp要好好练习,稍微难点就写不出来,=(

递归
  • 思路:

    我们在一个多边形中选择第一条边,然后选择其他任意一个顶点,与该边的两个顶点相连,那么我们得到了一个三角形和两个小多边形,那么该多边形进行三角剖分后的最低分为这三个图形进行剖分后的最低分之和,因此我们可以使用递归/dp解决该题

    因此可以定义递归函数dfs(i,j)dfs(i,j)dfs(i,j)表示从iiijjj的多边形的最低得分

    • 递归过程:枚举三角形的第三个顶点kkk,计算iiikkk的最低得分和kkkjjj的最低得分
      dfs(i,j)=mink=i+1j−1dfs(i,k)+dfs(k,j)+v[i]∗v[j]∗v[k] dfs(i,j)=min_{k=i+1}^{j-1}{dfs(i,k)+dfs(k,j)+v[i]*v[j]*v[k]} dfs(i,j)=mink=i+1j1dfs(i,k)+dfs(k,j)+v[i]v[j]v[k]

    • 递归边界

      dfs(i,i+1)=0dfs(i,i+1)=0dfs(i,i+1)=0 无法构成三角形

    • 递归入口

      dfs(0,n−1)dfs(0,n-1)dfs(0,n1)

  • 实现

    class Solution {
        private int[] v;
        private int[][] memo;
    
        public int minScoreTriangulation(int[] values) {
            v = values;
            int n = v.length;
            memo = new int[n][n];
            for (int i = 0; i < n; ++i)
                Arrays.fill(memo[i], -1); // -1 表示没有访问过
            return dfs(0, n - 1);
        }
    
        private int dfs(int i, int j) {
            if (i + 1 == j) return 0; // 只有两个点,无法组成三角形
            if (memo[i][j] != -1) return memo[i][j];
            int res = Integer.MAX_VALUE;
            for (int k = i + 1; k < j; ++k) // 枚举顶点 k
                res = Math.min(res, dfs(i, k) + dfs(k, j) + v[i] * v[j] * v[k]);
            return memo[i][j] = res;
        }
    }
    
    作者:灵茶山艾府
    链接:https://leetcode.cn/problems/minimum-score-triangulation-of-polygon/solutions/2203005/shi-pin-jiao-ni-yi-bu-bu-si-kao-dong-tai-aty6/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 复杂度

      • 时间复杂度:O(n3)O(n^3)O(n3)
      • 空间复杂度:O(n2)O(n^2)O(n2)
动态规划
  • 实现:外层逆序遍历i,内层正序遍历j和k

    • 由于 i<ki<ki<kf[i]f[i]f[i] 要能从 f[k]f[k]f[k] 转移过来,必须先计算出 f[k]f[k]f[k],所以 iii 要倒序枚举;
    • 由于 j>k,f[i][j]f[i][j]f[i][j]要能从 f[i][k]f[i][k]f[i][k]转移过来,必须先计算出 f[i][k]f[i][k]f[i][k],所以 jjj要正序枚举。
    class Solution {
        public int minScoreTriangulation(int[] v) {
            int n = v.length;
            int[][] f = new int[n][n];
            for (int i = n - 3; i >= 0; --i)
                for (int j = i + 2; j < n; ++j) {
                    f[i][j] = Integer.MAX_VALUE;
                    for (int k = i + 1; k < j; ++k)
                        f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + v[i] * v[j] * v[k]);
                }
            return f[0][n - 1];
        }
    }
    
    作者:灵茶山艾府
    链接:https://leetcode.cn/problems/minimum-score-triangulation-of-polygon/solutions/2203005/shi-pin-jiao-ni-yi-bu-bu-si-kao-dong-tai-aty6/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 复杂度

      • 时间复杂度:O(n3)O(n^3)O(n3)

      • 空间复杂度:O(n2)O(n^2)O(n2)

  • 实现:从小到大枚举区间长度,然后枚举iiij=i+len−1j=i+len-1j=i+len1,k∈[i+1,j−1]k \in [i+1,j-1]k[i+1,j1]

    class Solution {
        public int minScoreTriangulation(int[] values) {
            int n = values.length;
            int[][] dp = new int[n][n]; 
            for (int len = 3; len <= n; len++){
                for (int i = 0; i + len - 1 < n; i++){
                    int j = i + len - 1;
                    dp[i][j] = Integer.MAX_VALUE;
                    for (int k = i + 1; k < j; k++){
                        dp[i][j] = Math.min(dp[i][k] + dp[k][j] + values[i] * values[j] * values[k], dp[i][j]);
                    }
                }
            }
            return dp[0][n - 1];
        }
    
    
    }
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值