动态规划Ⅲ

343. 整数拆分

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积

思路:我们可以遍历正整数i之前的所有 j 对于正整数 i 可以拆解成 j + i-j ,那么有以下选择,第一个是 i -j 不再拆分,那么此时的乘积就是 j * (i-j),如果继续拆分,那么就是 j * dp[ i- j]。遍历时比较这两者与当前dp[i],取三者最大值。

 class Solution:
    def integerBreak(self, n: int) -> int:
        dp = [0] * (n + 1)   # 创建一个大小为n+1的数组来存储计算结果
        dp[2] = 1  # 初始化dp[2]为1,因为当n=2时,只有一个切割方式1+1=2,乘积为1
       
        # 从3开始计算,直到n
        for i in range(3, n + 1):
            # 遍历所有可能的切割点,遍历到 一半就可以,后面的跟前面是对称的
            for j in range(1, i // 2 + 1):

                # 计算切割点j和剩余部分(i-j)的乘积,并与之前的结果进行比较取较大值
                
                dp[i] = max(dp[i], (i - j) * j, dp[i - j] * j)
        
        return dp[-1]  # 返回最终的计算结果

  96. 不同的二叉搜索树 

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

思路:假设有n个数字,那么就有n个数可以作为头节点。假设该头节点为 i ,此时,头节点左侧的数有 i - 1 个,右侧的节点有n- i 个。各自的节点对应着 由 i -1 个节点组成的二叉搜索树和n-i个节点组成的二叉搜索树。那么它们各自的种树的积就是nge节点时的二叉搜索树的种数。因此,递推公式为:dp[i] += dp[j - 1] * dp[i - j]; ,j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量。dp[i] 的定义为有i个节点时的二叉搜索树的种数。

class Solution:
    def numTrees(self, n: int) -> int:
        dp = [0] * (n + 1)  
        dp[0] = 1  # 当n为0时,只有一种情况,即空树,所以dp[0] = 1
        for i in range(1, n + 1):  # 遍历从1到n的每个数字
            for j in range(1, i + 1):  # 对于每个数字i,计算以i为根节点的二叉搜索树的数量
                dp[i] += dp[j - 1] * dp[i - j]
        return dp[n]  

你可能感兴趣的:(动态规划,算法)