1130. 叶值的最小代价生成树

发布时间 2023-05-31 22:09:12作者: lixycc

题目链接:1130. 叶值的最小代价生成树

方法:dp

解题思路

  • 状态表示
    • 集合:\(dp[i][j]\) 表示子数组 \([i, j]\) 能构成的所有合法的二叉树集合;
    • 属性:\(dp[i][j]\) 的值表示集合中,二叉树非叶节点值和的其中最小值。
  • 状态计算
    • 集合划分:将子数组 \([i, j]\),划分为 \([i, k]\)\([k + 1, j]\) 对应的两个子集;
    • 计算:
      • \(i = j,dp[i][j] = 0\)
      • \(i\ != j,dp[i][j] = \min\limits_{k = i}^{j - 1}\{dp[i][k] + dp[k + 1][j] + mx[i][k] * mx[k + 1][j]\}\)

代码

class Solution {
public:
    int mctFromLeafValues(vector<int>& arr) {
        int n = arr.size();
        vector<vector<int>> dp(n, vector<int>(n, INT_MAX / 4)), mx(n, vector<int>(n));
        for (int i = 0; i < n; i ++ ) dp[i][i] = 0;
        for (int i = n - 1; i >= 0; i -- ) {
            mx[i][i] = arr[i];
            for (int j = i + 1; j < n; j ++ ) {
                mx[i][j] = max(arr[j], mx[i][j - 1]);
                for (int k = i; k < j; k ++ ) {
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + mx[i][k] * mx[k + 1][j]);
                }
            }
        }
        return dp[0][n - 1];
    }
};

复杂度分析

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