zoukankan      html  css  js  c++  java
  • 动态规划-区间dp-单调栈-1130. 叶值的最小代价生成树

    2020-05-07 16:17:23

    问题描述:

    给你一个正整数数组 arr,考虑所有满足以下条件的二叉树:

    每个节点都有 0 个或是 2 个子节点。
    数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。(知识回顾:如果一个节点有 0 个子节点,那么该节点为叶节点。)
    每个非叶节点的值等于其左子树和右子树中叶节点的最大值的乘积。
    在所有这样的二叉树中,返回每个非叶节点的值的最小可能总和。这个和的值是一个 32 位整数。

    示例:

    输入:arr = [6,2,4]
    输出:32
    解释:
    有两种可能的树,第一种的非叶节点的总和为 36,第二种非叶节点的总和为 32。

    24 24
    / /
    12 4 6 8
    / /
    6 2 2 4

    提示:

    2 <= arr.length <= 40
    1 <= arr[i] <= 15
    答案保证是一个 32 位带符号整数,即小于 2^31。

    问题求解:

    解法一:区间DP

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

        public int mctFromLeafValues(int[] arr) {
            int n = arr.length;
            int[][] dp = new int[n][n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (i == j) dp[i][j] = 0;
                    else dp[i][j] = Integer.MAX_VALUE;
                }
            }
            for (int len = 2; len <= n; len++) {
                for (int i = 0; i < n; i++) {
                    int j = i + len - 1;
                    if (j >= n) break;
                    for (int k = i; k < j; k++) {
                        dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k + 1][j] + helper(arr, i, k) * helper(arr, k + 1, j));
                    }
                }
            }
            return dp[0][n - 1];
        }
        
        private int helper(int[] arr, int l, int r) {
            int res = arr[l];
            for (int i = l; i <= r; i++) res = Math.max(res, arr[i]);
            return res;
        }
    

      

  • 相关阅读:
    python并发编程
    中缀表达式转换为后缀表达式(python实现)
    使用docker部署filebeat和logstash
    数据结构和算法的一些思考
    RESTFUL如何指导WEB API设计?
    哈希表的原理及实现代码
    python实现有序字典
    django源码分析 请求流程
    python 通过元类控制类的创建
    前后端分离人力资源管理系统
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12843753.html
Copyright © 2011-2022 走看看